Каков наилучший уровень изоляции транзакции по умолчанию для ERP, если таковой имеется? - PullRequest
14 голосов
/ 13 декабря 2008

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

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

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

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

Ответы [ 5 ]

16 голосов
/ 13 декабря 2008

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

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

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

2 голосов
/ 13 декабря 2008

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

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

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

2 голосов
/ 13 декабря 2008

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

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

1 голос
/ 13 декабря 2008

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

0 голосов
/ 14 декабря 2017

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

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

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

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

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

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

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

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

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

...