Каков наилучший уровень изоляции транзакции по умолчанию для ERP, если таковой имеется?

Краткая справка: мы только начинаем переносить / переопределять систему ERP на Java с помощью Hibernate, ориентируясь на число одновременных пользователей 50-100 пользователей, использующих систему. Мы используем MS SQL Server в качестве сервера базы данных, что достаточно для этой нагрузки.

Теперь старая система вообще не использует никаких транзакций и полагается на критические части (например, изменение запасов) на установку ручных блокировок (с использованием флагов) и их отпускание. Это что-то вроде ручного управления транзакциями. Но иногда возникают проблемы с несогласованностью данных. В новой системе мы хотели бы использовать транзакции для устранения этих проблем.

Теперь вопрос: какой будет хороший / разумный уровень изоляции транзакций по умолчанию для использования в системе ERP, учитывая использование около 85% OLTP и 15% OLAP? Или я должен всегда решать для каждой задачи, какой уровень транзакции использовать?

И в качестве напоминания четыре уровня изоляции транзакции: ЧИТАТЬ НЕОБЕСПЕЧЕННЫЙ, ЧИТАТЬ ЗАВЕРШЕНО, ПОВТОРЯЕТСЯ ЧИТАТЬ, СЕРИАЛИЗИРУЕМЫЙ

12.12.2008 21:54:45
5 ОТВЕТОВ
РЕШЕНИЕ

99 раз из 100, прочитанный совершенный - правильный ответ. Это гарантирует, что вы видите только те изменения, которые были зафиксированы другим сеансом (и, следовательно, результаты являются согласованными, если вы правильно разработали свои транзакции). Но это не накладывает накладные расходы на блокировку (особенно в базах данных не-Oracle), которые накладывают повторяемое чтение или сериализуемые данные.

В редких случаях вы можете захотеть запустить отчет, в котором вы готовы пожертвовать точностью ради скорости и установить уровень изоляции для чтения без фиксации. Это редко хорошая идея, но иногда это разумно приемлемый обходной путь для решения проблем конкуренции.

Сериализуемое и повторяемое чтение иногда используется, когда у вас есть процесс, который должен видеть непротиворечивый набор данных за весь прогон, независимо от того, какие другие транзакции делают в данный момент. Может быть целесообразно установить процесс сверки на конец месяца для сериализации, например, если имеется много процедурного кода, вероятность того, что пользователи будут вносить изменения во время выполнения процесса, и требование того, что процесс должен убедитесь, что он всегда видит данные в том виде, в каком они существовали на момент начала сверки.

18
12.12.2008 22:12:02
В зависимости от количества пользователей, я бы не советовал запускать отчеты в вашей основной системе OLTP. Поставьте журнал (или иным образом реплицированный) на стороне сервера для отчетов с денормализованной версией данных
chadmyers 12.12.2008 22:22:39

Для SQL Server (и, вероятно, большинства основных СУБД) я бы придерживался значения по умолчанию. Для SQL Server это READ COMMITTED. Все больше, и вы начинаете перегружать базу данных, меньше, и у вас возникают проблемы с согласованностью.

1
12.12.2008 22:06:15
По умолчанию для SQL Server может быть READ COMMITTED, но я считаю, что по умолчанию для ADO.net используется SERIALIZABLE, и в этом случае это имеет большее значение, если он использует .net.
Robert C. Barth 12.12.2008 22:08:14
@ Роберт Это не правильно. По умолчанию используется значение по умолчанию для SQL Server. Например, когда вы изменяете уровень изоляции в SqlTransaction, он выполняет SET TRANSACTION ISOLATION LEVEL XXXX на сервере.
chadmyers 14.12.2008 01:11:50

Не забывайте о SNAPSHOT, который находится под SERIALIZABLE.

Это зависит от того, насколько важно, чтобы данные были точными в отчетах. Это действительно задача за задачей.

2
12.12.2008 22:07:32

Это действительно сильно зависит от того, как вы разрабатываете свое приложение, простой ответ - READ_COMMITTED.

Вы можете привести аргумент, что если вы разрабатываете свою систему с учетом этого, вы можете использовать READ_UNCOMMITTED в качестве значения по умолчанию и повышать уровень изоляции только тогда, когда это необходимо. Подавляющее большинство ваших транзакций все равно будет успешным, поэтому чтение незафиксированных данных не будет иметь большого значения.

То, как уровни изоляции влияют на ваши запросы, зависит от вашей целевой базы данных. Например, базы данных, такие как Sybase и MSSQL, должны блокировать больше ресурсов при запуске READ_COMMITTED, чем базы данных, такие как Oracle.

2
12.12.2008 22:36:40

Чтение Uncommitted определенно является слабым местом на большинстве форумов. Тем не менее, есть причины использовать его, который выходит за рамки вопроса «скорость против точности», на который часто указывают.

Допустим, у вас есть:

  • Транзакция T1: пишет B, читает A, (еще немного работы), Commit.
  • Транзакция T2: записывает A, читает B, (еще немного работы), Commit.

При условии чтения совершено, транзакции, указанные выше, не будут освобождены до момента принятия. Затем вы можете столкнуться с ситуацией, когда T1 ожидает, когда T2 освободит A, а T2 ожидает, когда T1 освободит B. Здесь две транзакции сталкиваются в блокировке.

Вы можете переписать эти процедуры, чтобы избежать этого сценария (пример: получать ресурсы всегда в алфавитном порядке!). Тем не менее, из-за слишком большого количества одновременно работающих пользователей и десятков тысяч строк кода эта проблема может стать как очень вероятной, так и очень сложной для диагностики и решения.

Альтернативой является использование Read Uncommitted. Затем вы разрабатываете свои транзакции, предполагая, что может быть грязное чтение. Лично я считаю, что эта проблема гораздо более локализована и поддается лечению, чем взаимосвязанные железнодорожные аварии.

Проблемы от грязного чтения могут быть устранены

  • (1) Откаты: нет. Это должно быть последней линией защиты только в случае аппаратного сбоя, сбоя сети или сбоя программы.

  • (2) Используйте блокировки приложений для создания механизма блокировки, который работает на более высоком уровне абстракции, где каждая блокировка ближе к реальному ресурсу или действию.

0
14.12.2017 20:44:37