Длительные транзакции

6yrop

Правда, что в MS SQL рекомендуется не держать транзакцию более нескольких секунд? (говорят в документации такое написано, но я пока не нашел).
Реально ли делать транзакции, которые могут длиться больше месяца?

sergei1969

тоже слышал о таком
а нах такие транзакции?

Marikun

MS SQL Server из рук вон плохо работает с блокировками, поэтому с транзакциями надо быть поаккуратнее.
Объясни, зачем могут быть нужны транзакции, длящиеся несколько месяцев?

daru

Правда, что в MS SQL рекомендуется не держать транзакцию более нескольких секунд? (говорят в документации такое написано, но я пока не нашел).

Правда.
Цитата: Transactions left outstanding for long periods of time can prevent other users from accessing these locked resources. Связано это с реализацией механизма транзакций через блокировки (у ora через сегмент отката, например). Чем больше блокировок набрал, тем меньше остается ресурсов для параллельного исполнения запросов.
Реально ли делать транзакции, которые могут длиться больше месяца?

В каких-то ситуациях наверное да. Но смысл?

Dasar

Чем дольше ты держишь транзакцию, тем больше логических конфликтов возникает.
Причем именно логических, т.е. это не недостатки sql-я и не особенности конкретной реализации базы.
Откуда берутся такие конфликты - понятно?
Соответственно, чем короче транзакция, тем меньше вероятность, что возникнет нерешаемый конфликт.
Если задача требует таких длительностей, то лучше сделать поддержку таких транзакций на логическом уровне, и не поручать эти транзакции базе.

6yrop

а нах такие транзакции?

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

Если это в чистом виде транзакция, то почему не поручить?
Мне говорят одно слово "транзакция" без какой-либо расшифровки и при этом еще упоминают, что в MSSQL нельзя делать длительные транзакции, и это единственная причина, по которой около 10 программистов ваяют фишку, через которую я должен получать данные, хотя мне проще было бы обращаться к базе. Вообще, там, наверное, не совсем транзакции, но об этом надо говорить..........

Dasar

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

6yrop

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

Dasar

таких данных не достаточно, необходимо еще знать, какая транзакция важнее, какая менее важная, как разрешаются конфликты и т.д.
Расмотрим простую, но длинную транзакцию:
1. Insert into Table (key, data) values(13, "data")
2. update Table set data="another data" where key=13
и такую команду:
delete from table where key < 20
а теперь допустим, что эти команды выполняются в следующем порядке:
1. insert из первой транзакции
2. выполняется вторая транзакция
3. update из первой транзакции
допустим у нас все хорошо: есть идеальная всеумеющая база, и обе транзакции успешно выполнились.
Теперь вопросы:
1. А должны ли была база разрешить выполнить эти две транзакции параллельно? если не должна, то какая транзакция должна была быть снятой?
2. Что должно в результате получиться?
значение с ключом 13 в результате в базе должно быть или нет?

6yrop

Сначала выполнится полностью первая, потом вторая. Вторая будет ждать первую.

Dasar

т.е. вторая транзакция будет тоже висеть месяц?
рассмотрим следующую картинку:
1. есть маленькая, неважная транзакция, которая меняет одну запись
длительность у этой транзакции - 1 месяц
2. есть важная срочная транзакция, которая затрагивает большую часть базы и в том числе затрагивает первую запись.
получается, что вторая транзакция тоже висит месяц, как и первая
в итоге, из базы нельзя будет получить данные целый месяц, т.к. все последующие транзакции будут ждать вторую транзакцию, т.к. та затрагивает почти всю базу.

6yrop

тк в этом весь смысл транзакций. Как на твоем "логическом уровне" разрешить ситуацию доступа к первой записи?

123anna

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

Dasar

> этом весь смысл транзакций
это в простом случае, когда нет приоритетов у транзакций и т.д.
> Как на твоем "логическом уровне" разрешить ситуацию доступа к первой записи?
логический уровень может принять следующие решения:
1. Невыполнить вторую транзакцию, т.к. не допустимо, чтобы такая большая транзакция висела месяц
2. Убить первую транзакцию
3. поменять местами вторую и первую транзакцию: откатить первую, накатить вторую, накатить опять первую.
4. Поддержть несколько копий базы одновременно: выполнив вторую транзакцию на обоих копиях независимо
соответственно одна копия считает, что первая транзакция выполнится успешно
вторая копия считает, что первая транзакция откатится.
и т.д.
Рассмотрим такой прикладной сценарий:
есть некий сложный товар продавцы его продают
соответственно, каждая продажа выглядит как следующая транзакция:
зарезервировать товар на складе
дождаться подписание договора
получить деньги и отгрузить товар
подписание договора может длиться долгое время, соответственно такая транзакция может висеть не один месяц.
Далее допустим на складе происходит пожар, и часть товара сгорает, соответсвенно запускается вторая транзакция, которая обновляет информацию во всей базе.
В данном случае логический уровень мог попытаться пойти по 3 сценарию, откатить первую транзакцию, накатить изменение базы, попытаться накатить первую транзакцию, если не получилось, то сообщить об этой печальной новости покупателю.

Dasar

> Транзакция, которая выполняется долго, изменяет много записей, а не одну.
Не обязательно: в транзакцию могут быть объединены: чтение, с последующей одиночной записью, могут даже быть объединены два и более чтения без какой-либо записи.
пример прикладной задачи:
получить снимок части базы на определенный момент: транзакция есть, но никаких записей нет.

rid2000


1. А должны ли была база разрешить выполнить эти две транзакции параллельно? если не должна, то какая транзакция должна была быть снятой?
2. Что должно в результате получиться?

1. По поводу транзакций, есть множество алгоритмов сериализации и разрешения конфликтов...
2. Параллельно они не будут выполняться ! Потому что есть конфликт по WW
получается, что вторая транзакция тоже висит месяц, как и первая

3. Результат зависит - от приоритетов и прав... Если у первой приоритет больше, то будет ждать - тут все логично...
А вот если у второй приоритет больше... то тут... хз... хотя логично будет откатить первую полностью, т.к. у них конфликт.. Но...
Мы же говорим о многопользовательской СУБД, то тут проблема несогласованости пользователей. А БД останется в согласованном состоянии (на первый взгляд, хотя нет условий согласования)

6yrop

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

Dasar

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

6yrop

да

какая же это тогда транзакция. Для транзакции всё должно происходить, так как будто кроме этой транзакции никто не работает с базой.

6yrop

и что с отданным на подпись договором делать, цена в нем старая.

Dasar

> Для транзакции всё должно происходить, так как будто кроме этой транзакции никто не работает с базой.
Это удобное идеалистическое допущение - не более.

6yrop

ха-ха, что же тогда по-твоему транзакция?

Dasar

так это и есть задача уровня бизнес-логики

rid2000

Для транзакции всё должно происходить, так как будто кроме этой транзакции никто не работает с базой.

Это определение транзакции !

Dasar

если кратко: транзакция - это совместно выполняемые действия, которые в общем случае, либо все выполняются, либо все откатываются.

6yrop

в первую очередь надо определить результат выполнения или отката последовательности действий.

Dasar

Допустим у нас есть следующие две транзакции, со следующими трассами выполнения:


1 транзакция. увеличить a на 1
2 транзакция. увеличить a на 100000
1 транзакция. уменьшить a на 1
2 транзакция. уменьшить a на 100000


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

6yrop

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


1 транзакция. увеличить a на 4
2 транзакция. умножить а на 2
1 транзакция. уменьшить a на 4
2 транзакция. разделить a на 2




1 транзакция. увеличить a на 4
1 транзакция. уменьшить a на 4
2 транзакция. умножить а на 2
2 транзакция. разделить a на 2

Dasar

Так вот здесь и начинается самое интересное:
у нас есть база, на ней бегает куча транзакций,
теперь запускаем еще одну транзакцию
вопрос:
над каким состоянием базы, запущенная транзакция должна выполниться?
1. над состоянием, предшествующим всем запущенным в данный момент транзакциям.
2. над состоянием, которое получится после выполнения всех запущенных транзакций
3. над всеми возможными состояниями, которые получаются в результате выполнения/отката текущих запущенных транзакций
и т.д.

6yrop

над состоянием базы, которое было в момент запуска транзакции.
(Если не получится дедлока, то отработают все тарнзакции)

6yrop

измениея, сделанные незавершенными транзакциями не входят в состояние базы, т.е. вариант 1.

Dasar

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

6yrop

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

Dasar

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

Dasar

в данные, как минимум входит время, а также результирующие данные зависят от порядка выполнения.
взять, например, транзакции запущенные параллельно, которые имеют следующие фрагменты:


1 транзакция:
...
update Table set a=a+1 where a = 10
...
2 Транзакция:
...
update Table set a=a-1 where a = 10
...


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

rid2000


Поддержание механизма транзакций - показатель уровня развитости СУБД. Корректное поддержание транзакций одновременно является основой обеспечения целостности баз данных (и поэтому транзакции вполне уместны и в однопользовательских персональных СУБД а также составляют базис изолированности пользователей во многопользовательских системах. Часто эти два аспекта рассматриваются по отдельности, но на самом деле они взаимосвязаны.
Заметим, что хотя с точки зрения обеспечения целостности баз данных механизм транзакций следовало бы поддерживать в персональных СУБД, на практике это обычно не выполняется. Поэтому при переходе от персональных к многопользовательским СУБД пользователи сталкиваются с необходимостью четкого понимания природы транзакций.
Под транзакцией понимается неделимая с точки зрения воздействия на БД последовательность операторов манипулирования данными (чтения, удаления, вставки, модификации) такая, что либо результаты всех операторов, входящих в транзакцию, отображаются в БД, либо воздействие всех этих операторов полностью отсутствует. Лозунг транзакции - "Все или ничего": при завершении транзакции оператором COMMIT результаты гарантированно фиксируются во внешней памяти (смысл слова commit - "зафиксировать" результаты транзакции); при завершении транзакции оператором ROLLBACK результаты гарантированно отсутствуют во внешней памяти (смысл слова rollback - ликвидировать результаты транзакции).
системах с развитыми средствами ограничения и контроля целостности каждая транзакция начинается при целостном состоянии БД и должна оставить это состояние целостными после своего завершения. Несоблюдение этого условия приводит к тому, что вместо фиксации результатов транзакции происходит ее откат (т.е. вместо оператора COMMIT выполняется оператор ROLLBACK и БД остается в таком состоянии, в котором находилась к моменту начала транзакции, т.е. в целостном состоянии.
Понятно, что для того, чтобы добиться изолированности транзакций, в СУБД должны использоваться какие-либо методы регулирования совместного выполнения транзакций.
План (способ) выполнения набора транзакций называется сериальным, если результат совместного выполнения транзакций эквивалентен результату некоторого последовательного выполнения этих же транзакций.
Сериализация транзакций - это механизм их выполнения по некоторому сериальному плану. Обеспечение такого механизма является основной функцией компонента СУБД, ответственного за управление транзакциями. Система, в которой поддерживается сериализация транзакций обеспечивает реальную изолированность пользователей.
Основная реализационная проблема состоит в выборе метода сериализации набора транзакций, который не слишком ограничивал бы их параллельность. Приходящим на ум тривиальным решением является действительно последовательное выполнение транзакций. Но существуют ситуации, в которых можно выполнять операторы разных транзакций в любом порядке с сохранением сериальности. Примерами могут служить только читающие транзакции, а также транзакции, не конфликтующие по объектам базы данных.
Между транзакциями могут существовать следующие виды конфликтов:
W-W - транзакция 2 пытается изменять объект, измененный не закончившейся транзакцией 1;
R-W - транзакция 2 пытается изменять объект, прочитанный не закончившейся транзакцией 1;
W-R - транзакция 2 пытается читать объект, измененный не закончившейся транзакцией 1.
Существуют два базовых подхода к сериализации транзакций - основанный на синхронизационных захватах объектов базы данных и на использовании временных меток. Суть обоих подходов состоит в обнаружении конфликтов транзакций и их устранении.

Dasar

План (способ) выполнения набора транзакций называется сериальным, если результат совместного выполнения транзакций эквивалентен результату некоторого последовательного выполнения этих же транзакций.
дык, так самое интересное пропущено:
1. не определено, что такое совместное выполнение транзакций
2. не сказано, что делать если не существует такого сериального плана.
и т.д.

rid2000

Во первых: некоторого последовательного выполнения этих же транзакций - т.е. определенной...
Во вторых - сильно не вдавался, но теоритически он существует...
Есть методы сериализации - посмотри их...

sergey_m

Транзакция, которая выполняется долго, изменяет много записей, а не одну. Это аксиома. Соответственно, она очень важная, и это нормально, когда ее все ждут. И пользователь, который ее замутил, должен это понимать. Возможное послабление: во время ее выполнения можно считать старую базу актуальной и разрешить ее чтение; а изменять копию базы.
IMHO.
То, что ты описал называется версионная архитектура транзакций. А в MSSQL архитектура транзакций блокировочная. На нём так не прокатит имхо.

Dasar

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

6yrop

ок, я был неточен, я имел ввиду, что транзакция не должна чувствовать, что кроме нее кто-то еще меняет состояние базы.

rid2000

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

6yrop

т.е. получается, что транзакции лежащие в РБД априори подразумевают, что никакого совместного(параллельного) выполнения транзакций не бывает, а есть только последовательное выполнение транзакций.

как ты себе представляешь параллельное выполнение транзакций?
Если 2-ая транзакция увидит изменения, сделанные 1-ой, и сделает некоторые действия на основе полученной информации, как сделать откат?

rid2000


Во многопользовательских системах с одной базой данных одновременно могут работать несколько пользователей или прикладных программ. Предельной задачей системы является обеспечение изолированности пользователей, т.е. создание достоверной и надежной иллюзии того, что каждый из пользователей работает с БД в одиночку.
В связи со свойством сохранения целостности БД транзакции являются подходящими единицами изолированности пользователей. Действительно, если с каждым сеансом работы с базой данных ассоциируется транзакция, то каждый пользователь начинает работу с согласованным состоянием базы данных, т.е. с таким состоянием, в котором база данных могла бы находиться, даже если бы пользователь работал с ней в одиночку.
При соблюдении обязательного требования поддержания целостности базы данных возможны следующие уровни изолированности транзакций:
----Первый уровень - отсутствие потерянных изменений. Рассмотрим следующий сценарий совместного выполнения двух транзакций. Транзакция 1 изменяет объект базы данных A. До завершения транзакции 1 транзакция 2 также изменяет объект A. Транзакция 2 завершается оператором ROLLBACK (например, по причине нарушения ограничений целостности). Тогда при повторном чтении объекта A транзакция 1 не видит изменений этого объекта, произведенных ранее. Такая ситуация называется ситуацией потерянных изменений. Естественно, она противоречит требованию изолированности пользователей. Чтобы избежать такой ситуации в транзакции 1 требуется, чтобы до завершения транзакции 1 никакая другая транзакция не могла изменять объект A. Отсутствие потерянных изменений является минимальным требованием к СУБД по части синхронизации параллельно выполняемых транзакций.
----Второй уровень - отсутствие чтения "грязных данных". Рассмотрим следующий сценарий совместного выполнения транзакций 1 и 2. Транзакция 1 изменяет объект базы данных A. Параллельно с этим транзакция 2 читает объект A. Поскольку операция изменения еще не завершена, транзакция 2 видит несогласованные "грязные" данные (в частности, операция транзакции 1 может быть отвернута при проверке немедленно проверяемого ограничения целостности). Это тоже не соответствует требованию изолированности пользователей (каждый пользователь начинает свою транзакцию при согласованном состоянии базы данных и в праве ожидать видеть согласованные данные). Чтобы избежать ситуации чтения "грязных" данных, до завершения транзакции 1, изменившей объект A, никакая другая транзакция не должна читать объект A (минимальным требованием является блокировка чтения объекта A до завершения операции его изменения в транзакции 1).
----Третий уровень - отсутствие неповторяющихся чтений. Рассмотрим следующий сценарий. Транзакция 1 читает объект базы данных A. До завершения транзакции 1 транзакция 2 изменяет объект A и успешно завершается оператором COMMIT. Транзакция 1 повторно читает объект A и видит его измененное состояние. Чтобы избежать неповторяющихся чтений, до завершения транзакции 1 никакая другая транзакция не должна изменять объект A. В большинстве систем это является максимальным требованием к синхронизации транзакций, хотя, как мы увидим немного позже, отсутствие неповторяющихся чтений еще не гарантирует реальной изолированности пользователей.
Заметим, что существует возможность обеспечения разных уровней изолированности для разных транзакций, выполняющихся в одной системе баз данных (в частности, соответствующие операторы предусмотрены в стандарте SQL 2). Как мы уже отмечали, для поддержания целостности достаточен первый уровень. Существует ряд приложений, для которых первого уровня достаточно (например, прикладные или системные статистические утилиты, для которых некорректность индивидуальных данных несущественна). При этом удается существенно сократить накладные расходы СУБД и повысить общую эффективность.
К более тонким проблемам изолированности транзакций относится так называемая проблема кортежей-"фантомов", вызывающая ситуации, которые также противоречат изолированности пользователей. Рассмотрим следующий сценарий. Транзакция 1 выполняет оператор A выборки кортежей отношения R с условием выборки S (т.е. выбирается часть кортежей отношения R, удовлетворяющих условию S). До завершения транзакции 1 транзакция 2 вставляет в отношение R новый кортеж r, удовлетворяющий условию S, и успешно завершается. Транзакция 1 повторно выполняет оператор A, и в результате появляется кортеж, который отсутствовал при первом выполнении оператора. Конечно, такая ситуация противоречит идее изолированности транзакций и может возникнуть даже на третьем уровне изолированности транзакций. Чтобы избежать появления кортежей-фантомов, требуется более высокий "логический" уровень синхронизации транзакций. Идеи такой синхронизации (предикатные синхронизационные захваты) известны давно, но в большинстве систем не реализованы.

rid2000

На ситфоруме описаны методы сериализации:
- Синхронизационные захваты
- Метод временных меток
Существуют два базовых подхода к сериализации транзакций - основанный на синхронизационных захватах объектов базы данных и на использовании временных меток. Суть обоих подходов состоит в обнаружении конфликтов транзакций и их устранении.

Dasar

> Если 2-ая транзакция увидит изменения, сделанные 1-ой, и сделает некоторые действия на основе полученной информации, как сделать откат?
базы построенные на версионном механизме умеют решать данные проблемы.
> как ты себе представляешь параллельное выполнение транзакций?
не получается сформулировать.

6yrop

так может быть 2-ая транзакция накормила меня ужином, и я его уже съел.

Dasar

> так может быть 2-ая транзакция накормила меня ужином, и я его уже съел.
Замечание не понял.

daru


> как ты себе представляешь параллельное выполнение транзакций?
не получается сформулировать.
А давайте почитаем тут, например. Здесь описаны различные отношения между транзакциями в реляционных БД. Примеры на C++, а теория - применительно к MS SQL Server. По-моему, должно прекратить нарастающий флуд :-)

rid2000

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

Поэтому, НИКАКОЙ ПАРАЛЛЕЛЬНОСТИ НЕТ ! - в смысле идеологической...

6yrop

Спасибо конечно, может как-нибудь найдется время почитать, но в этой статье
упор делается в основном на механизм блокировок, его внутреннее устройство и использование в СУБД MS SQL Server 2000. Предполагается, что читатель хорошо знаком с транзакциями и их свойствами.
а в треде шел разговор о понятии "транзакция".
Оставить комментарий
Имя или ник:
Комментарий: