Длительные транзакции
а нах такие транзакции?
Объясни, зачем могут быть нужны транзакции, длящиеся несколько месяцев?
Правда, что в MS SQL рекомендуется не держать транзакцию более нескольких секунд? (говорят в документации такое написано, но я пока не нашел).
Правда.
Цитата: Transactions left outstanding for long periods of time can prevent other users from accessing these locked resources. Связано это с реализацией механизма транзакций через блокировки (у ora через сегмент отката, например). Чем больше блокировок набрал, тем меньше остается ресурсов для параллельного исполнения запросов.
Реально ли делать транзакции, которые могут длиться больше месяца?
В каких-то ситуациях наверное да. Но смысл?
Причем именно логических, т.е. это не недостатки sql-я и не особенности конкретной реализации базы.
Откуда берутся такие конфликты - понятно?
Соответственно, чем короче транзакция, тем меньше вероятность, что возникнет нерешаемый конфликт.
Если задача требует таких длительностей, то лучше сделать поддержку таких транзакций на логическом уровне, и не поручать эти транзакции базе.
а нах такие транзакции?
на этот вопрос я не могу ответить, поскольку еще не разобрался, поэтому всё это будет напоминать флуд.......
Если задача требует таких длительностей, то лучше сделать поддержку таких транзакций на логическом уровне, и не поручать эти транзакции базе.
Если это в чистом виде транзакция, то почему не поручить?
Мне говорят одно слово "транзакция" без какой-либо расшифровки и при этом еще упоминают, что в MSSQL нельзя делать длительные транзакции, и это единственная причина, по которой около 10 программистов ваяют фишку, через которую я должен получать данные, хотя мне проще было бы обращаться к базе. Вообще, там, наверное, не совсем транзакции, но об этом надо говорить..........
Потому что базе не хватит знаний для решения конфликтов, возникающих на логическом уровне.
данные можно либо читать, либо обновлять. Поэтому для обеспечения независимого прараллельно доступа к данным вполне достаточно знаний о том, что данные читают, обновляют, ничего с ними не делают.
Расмотрим простую, но длинную транзакцию:
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 в результате в базе должно быть или нет?
Сначала выполнится полностью первая, потом вторая. Вторая будет ждать первую.
рассмотрим следующую картинку:
1. есть маленькая, неважная транзакция, которая меняет одну запись
длительность у этой транзакции - 1 месяц
2. есть важная срочная транзакция, которая затрагивает большую часть базы и в том числе затрагивает первую запись.
получается, что вторая транзакция тоже висит месяц, как и первая
в итоге, из базы нельзя будет получить данные целый месяц, т.к. все последующие транзакции будут ждать вторую транзакцию, т.к. та затрагивает почти всю базу.
тк в этом весь смысл транзакций. Как на твоем "логическом уровне" разрешить ситуацию доступа к первой записи?
IMHO.
это в простом случае, когда нет приоритетов у транзакций и т.д.
> Как на твоем "логическом уровне" разрешить ситуацию доступа к первой записи?
логический уровень может принять следующие решения:
1. Невыполнить вторую транзакцию, т.к. не допустимо, чтобы такая большая транзакция висела месяц
2. Убить первую транзакцию
3. поменять местами вторую и первую транзакцию: откатить первую, накатить вторую, накатить опять первую.
4. Поддержть несколько копий базы одновременно: выполнив вторую транзакцию на обоих копиях независимо
соответственно одна копия считает, что первая транзакция выполнится успешно
вторая копия считает, что первая транзакция откатится.
и т.д.
Рассмотрим такой прикладной сценарий:
есть некий сложный товар продавцы его продают
соответственно, каждая продажа выглядит как следующая транзакция:
зарезервировать товар на складе
дождаться подписание договора
получить деньги и отгрузить товар
подписание договора может длиться долгое время, соответственно такая транзакция может висеть не один месяц.
Далее допустим на складе происходит пожар, и часть товара сгорает, соответсвенно запускается вторая транзакция, которая обновляет информацию во всей базе.
В данном случае логический уровень мог попытаться пойти по 3 сценарию, откатить первую транзакцию, накатить изменение базы, попытаться накатить первую транзакцию, если не получилось, то сообщить об этой печальной новости покупателю.
Не обязательно: в транзакцию могут быть объединены: чтение, с последующей одиночной записью, могут даже быть объединены два и более чтения без какой-либо записи.
пример прикладной задачи:
получить снимок части базы на определенный момент: транзакция есть, но никаких записей нет.
1. А должны ли была база разрешить выполнить эти две транзакции параллельно? если не должна, то какая транзакция должна была быть снятой?
2. Что должно в результате получиться?
1. По поводу транзакций, есть множество алгоритмов сериализации и разрешения конфликтов...
2. Параллельно они не будут выполняться ! Потому что есть конфликт по WW
получается, что вторая транзакция тоже висит месяц, как и первая
3. Результат зависит - от приоритетов и прав... Если у первой приоритет больше, то будет ждать - тут все логично...
А вот если у второй приоритет больше... то тут... хз... хотя логично будет откатить первую полностью, т.к. у них конфликт.. Но...
Мы же говорим о многопользовательской СУБД, то тут проблема несогласованости пользователей. А БД останется в согласованном состоянии (на первый взгляд, хотя нет условий согласования)
При откате и последующем накате могут сгенерироваться разные номера договоров, а на подпись ушел первый договор.
да
> При откате и последующем накате могут сгенерироваться разные номера договоров, а на подпись ушел первый договор.
эти проблемы как раз и должен, и может решить логический уровень.
да
какая же это тогда транзакция. Для транзакции всё должно происходить, так как будто кроме этой транзакции никто не работает с базой.
и что с отданным на подпись договором делать, цена в нем старая.
Это удобное идеалистическое допущение - не более.
ха-ха, что же тогда по-твоему транзакция?
так это и есть задача уровня бизнес-логики
Для транзакции всё должно происходить, так как будто кроме этой транзакции никто не работает с базой.
Это определение транзакции !
если кратко: транзакция - это совместно выполняемые действия, которые в общем случае, либо все выполняются, либо все откатываются.
в первую очередь надо определить результат выполнения или отката последовательности действий.
1 транзакция. увеличить a на 1
2 транзакция. увеличить a на 100000
1 транзакция. уменьшить a на 1
2 транзакция. уменьшить a на 100000
Можно ли эти транзакции выполнить параллельно на идеальной базе? да, можно
Можно ли эти транзакции выполнить параллельно на современной базе? нет, нельзя
Можно ли считать, что каждая из транзакций выполняется обособленно? да, на определенном уровне абстракции
можно ли в любом случае, считать, что транзакции выполняются независимо?. нет, нельзя, т.к. есть, например, переполнения a, есть тригеры, которые висят на a и т.д.
вот такие последовательности действий уже не эквивалентны
1 транзакция. увеличить a на 4
2 транзакция. умножить а на 2
1 транзакция. уменьшить a на 4
2 транзакция. разделить a на 2
1 транзакция. увеличить a на 4
1 транзакция. уменьшить a на 4
2 транзакция. умножить а на 2
2 транзакция. разделить a на 2
у нас есть база, на ней бегает куча транзакций,
теперь запускаем еще одну транзакцию
вопрос:
над каким состоянием базы, запущенная транзакция должна выполниться?
1. над состоянием, предшествующим всем запущенным в данный момент транзакциям.
2. над состоянием, которое получится после выполнения всех запущенных транзакций
3. над всеми возможными состояниями, которые получаются в результате выполнения/отката текущих запущенных транзакций
и т.д.
(Если не получится дедлока, то отработают все тарнзакции)
измениея, сделанные незавершенными транзакциями не входят в состояние базы, т.е. вариант 1.
надеюсь понятно, что это некое идеалистическое пожелание, которое в общем случае не имеет ничего общего с действительностью.
Ps
в состояние базы, входит также, например, размер базы, состояние журналов базы, время и порядок запуска транзакций и т.д.
но оно вполне работоспособно. Ты так и не показал, где оно не работает.
>в состояние базы, входит также, например, размер базы, состояние журналов базы, время и порядок запуска транзакций и т.д.
меня интересуют только данные. Читая текст на листе бумаги, ты же не интересуешься сколько весит листок бумаги.
транзакции - это некая модель, и как свойственно всякой модели, транзакции тоже не могут описать мир полностью.
причем те транзакции, которые положены в модель РБД - очень простые, в этом и есть весомый плюс таких транзакций, т.к. позволяет с более меньшими ресурсами описывать задачи.
и в этом же есть весомый минус - т.к. не позволяет описывать(учитывать) сложные аспекты действительности: время, расход ресурсов на выполнение невыполненных транзакций, недетерминированность и т.д.
если транзакции реализуются на логическом уровне, то модель таких транзакций может уже быть более полной (лучше учитывать прикладную специфику такие транзакции уже могут принимать во внимание и вышеприведенные тонкости в том числе.
взять, например, транзакции запущенные параллельно, которые имеют следующие фрагменты:
1 транзакция:
...
update Table set a=a+1 where a = 10
...
2 Транзакция:
...
update Table set a=a-1 where a = 10
...
при запуске этих транзакций параллельно результат будет неопределенный и зависит от того, какая используется модель блокировок, какая транзакция успеет быстрее заблокировать конфликтную запись и т.д.
ps
если исходить из твоего определения, что транзакции работают с тем состоянием, которые было до запуска параллельно выполняемых транзакций, то получается, что мы вправе рассчитывать, что обе эти транзакции произведут взаимообратные дейстия и в результате мы получим опять 10
Поддержание механизма транзакций - показатель уровня развитости СУБД. Корректное поддержание транзакций одновременно является основой обеспечения целостности баз данных (и поэтому транзакции вполне уместны и в однопользовательских персональных СУБД а также составляют базис изолированности пользователей во многопользовательских системах. Часто эти два аспекта рассматриваются по отдельности, но на самом деле они взаимосвязаны.
Заметим, что хотя с точки зрения обеспечения целостности баз данных механизм транзакций следовало бы поддерживать в персональных СУБД, на практике это обычно не выполняется. Поэтому при переходе от персональных к многопользовательским СУБД пользователи сталкиваются с необходимостью четкого понимания природы транзакций.
Под транзакцией понимается неделимая с точки зрения воздействия на БД последовательность операторов манипулирования данными (чтения, удаления, вставки, модификации) такая, что либо результаты всех операторов, входящих в транзакцию, отображаются в БД, либо воздействие всех этих операторов полностью отсутствует. Лозунг транзакции - "Все или ничего": при завершении транзакции оператором COMMIT результаты гарантированно фиксируются во внешней памяти (смысл слова commit - "зафиксировать" результаты транзакции); при завершении транзакции оператором ROLLBACK результаты гарантированно отсутствуют во внешней памяти (смысл слова rollback - ликвидировать результаты транзакции).
системах с развитыми средствами ограничения и контроля целостности каждая транзакция начинается при целостном состоянии БД и должна оставить это состояние целостными после своего завершения. Несоблюдение этого условия приводит к тому, что вместо фиксации результатов транзакции происходит ее откат (т.е. вместо оператора COMMIT выполняется оператор ROLLBACK и БД остается в таком состоянии, в котором находилась к моменту начала транзакции, т.е. в целостном состоянии.
Понятно, что для того, чтобы добиться изолированности транзакций, в СУБД должны использоваться какие-либо методы регулирования совместного выполнения транзакций.
План (способ) выполнения набора транзакций называется сериальным, если результат совместного выполнения транзакций эквивалентен результату некоторого последовательного выполнения этих же транзакций.
Сериализация транзакций - это механизм их выполнения по некоторому сериальному плану. Обеспечение такого механизма является основной функцией компонента СУБД, ответственного за управление транзакциями. Система, в которой поддерживается сериализация транзакций обеспечивает реальную изолированность пользователей.
Основная реализационная проблема состоит в выборе метода сериализации набора транзакций, который не слишком ограничивал бы их параллельность. Приходящим на ум тривиальным решением является действительно последовательное выполнение транзакций. Но существуют ситуации, в которых можно выполнять операторы разных транзакций в любом порядке с сохранением сериальности. Примерами могут служить только читающие транзакции, а также транзакции, не конфликтующие по объектам базы данных.
Между транзакциями могут существовать следующие виды конфликтов:
W-W - транзакция 2 пытается изменять объект, измененный не закончившейся транзакцией 1;
R-W - транзакция 2 пытается изменять объект, прочитанный не закончившейся транзакцией 1;
W-R - транзакция 2 пытается читать объект, измененный не закончившейся транзакцией 1.
Существуют два базовых подхода к сериализации транзакций - основанный на синхронизационных захватах объектов базы данных и на использовании временных меток. Суть обоих подходов состоит в обнаружении конфликтов транзакций и их устранении.
План (способ) выполнения набора транзакций называется сериальным, если результат совместного выполнения транзакций эквивалентен результату некоторого последовательного выполнения этих же транзакций.дык, так самое интересное пропущено:
1. не определено, что такое совместное выполнение транзакций
2. не сказано, что делать если не существует такого сериального плана.
и т.д.
Во вторых - сильно не вдавался, но теоритически он существует...
Есть методы сериализации - посмотри их...
Транзакция, которая выполняется долго, изменяет много записей, а не одну. Это аксиома. Соответственно, она очень важная, и это нормально, когда ее все ждут. И пользователь, который ее замутил, должен это понимать. Возможное послабление: во время ее выполнения можно считать старую базу актуальной и разрешить ее чтение; а изменять копию базы.То, что ты описал называется версионная архитектура транзакций. А в MSSQL архитектура транзакций блокировочная. На нём так не прокатит имхо.
IMHO.
т.е. получается, что транзакции лежащие в РБД априори подразумевают, что никакого совместного(параллельного) выполнения транзакций не бывает, а есть только последовательное выполнение транзакций.
т.е. транзакции в РБД - это некая упрощенная модель, что и требовалось доказать.
ок, я был неточен, я имел ввиду, что транзакция не должна чувствовать, что кроме нее кто-то еще меняет состояние базы.
Там говориться об эффекте (сравнение результатов работы) после выполнения... Т.е. результат паралельного(сериального) выполнения транзакций тождественно равна результату, если бы мы выполняли последовательно эти транзакций.
т.е. получается, что транзакции лежащие в РБД априори подразумевают, что никакого совместного(параллельного) выполнения транзакций не бывает, а есть только последовательное выполнение транзакций.
как ты себе представляешь параллельное выполнение транзакций?
Если 2-ая транзакция увидит изменения, сделанные 1-ой, и сделает некоторые действия на основе полученной информации, как сделать откат?
Во многопользовательских системах с одной базой данных одновременно могут работать несколько пользователей или прикладных программ. Предельной задачей системы является обеспечение изолированности пользователей, т.е. создание достоверной и надежной иллюзии того, что каждый из пользователей работает с БД в одиночку.
В связи со свойством сохранения целостности БД транзакции являются подходящими единицами изолированности пользователей. Действительно, если с каждым сеансом работы с базой данных ассоциируется транзакция, то каждый пользователь начинает работу с согласованным состоянием базы данных, т.е. с таким состоянием, в котором база данных могла бы находиться, даже если бы пользователь работал с ней в одиночку.
При соблюдении обязательного требования поддержания целостности базы данных возможны следующие уровни изолированности транзакций:
----Первый уровень - отсутствие потерянных изменений. Рассмотрим следующий сценарий совместного выполнения двух транзакций. Транзакция 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, и в результате появляется кортеж, который отсутствовал при первом выполнении оператора. Конечно, такая ситуация противоречит идее изолированности транзакций и может возникнуть даже на третьем уровне изолированности транзакций. Чтобы избежать появления кортежей-фантомов, требуется более высокий "логический" уровень синхронизации транзакций. Идеи такой синхронизации (предикатные синхронизационные захваты) известны давно, но в большинстве систем не реализованы.
- Синхронизационные захваты
- Метод временных меток
Существуют два базовых подхода к сериализации транзакций - основанный на синхронизационных захватах объектов базы данных и на использовании временных меток. Суть обоих подходов состоит в обнаружении конфликтов транзакций и их устранении.
базы построенные на версионном механизме умеют решать данные проблемы.
> как ты себе представляешь параллельное выполнение транзакций?
не получается сформулировать.
так может быть 2-ая транзакция накормила меня ужином, и я его уже съел.
Замечание не понял.
А давайте почитаем тут, например. Здесь описаны различные отношения между транзакциями в реляционных БД. Примеры на C++, а теория - применительно к MS SQL Server. По-моему, должно прекратить нарастающий флуд :-)
> как ты себе представляешь параллельное выполнение транзакций?
не получается сформулировать.
Isolation (изолированность). Транзакции должны выполнятся автономно и независимо от других транзакций. При одновременном выполнении множества конкурирующих друг с другом транзакций, любое обновление определенной транзакции будет скрыто от остальных до тех пор, пока эта транзакция не будет зафиксирована. Существуют несколько уровней изолированности (изоляции) транзакций, которые позволяют выбрать наиболее оптимальное решение с точки зрения производительности и целостности данных. Основным методом реализации этих уровней и являются блокировки, о которых пойдет речь в этой статье.
Поэтому, НИКАКОЙ ПАРАЛЛЕЛЬНОСТИ НЕТ ! - в смысле идеологической...
упор делается в основном на механизм блокировок, его внутреннее устройство и использование в СУБД MS SQL Server 2000. Предполагается, что читатель хорошо знаком с транзакциями и их свойствами.а в треде шел разговор о понятии "транзакция".
Оставить комментарий
6yrop
Правда, что в MS SQL рекомендуется не держать транзакцию более нескольких секунд? (говорят в документации такое написано, но я пока не нашел).Реально ли делать транзакции, которые могут длиться больше месяца?