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

Translate

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

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

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

Напоминаем, что четыре уровня изоляции транзакций: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE.

This question and all comments follow the "Attribution Required."

Все ответы

Translate

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

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

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

Источник
Translate

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

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

Источник
Translate

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

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

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

Источник
Translate

Для SQL Server (и, вероятно, большинства основных СУБД) я бы придерживался значения по умолчанию. Для SQL Server это ЧТЕНИЕ ЗАВЕРШЕНО. Что-то большее, и вы начинаете перенапрягать БД, что-то меньшее, и у вас возникают проблемы с согласованностью.

Источник
Translate

Read Uncommitted - определенно неудачник на большинстве форумов. Однако есть причины использовать его, выходящие за рамки часто указываемого вопроса «скорость против точности».

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

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

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

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

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

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

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

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

Источник
Leave a Reply
You must be logged in to post a answer.
Об авторе