транзакції, тобто зворотне виконання всіх змін, вироблених в даній транзакції, і відновлення стану сканів. Відкат може бути зроблений до початку транзакції (в цьому випадку про відновлення стану сканів говорити безглуздо) або до встановленої раніше в транзакції точці збереження.
Точка збереження встановлюється за допомогою операції SAVE. При виконанні цієї операції запам'ятовується стан сканів даної транзакції, відкритих до моменту виконання SAVE, і координати останнього запису про зміни в базі даних в журналі, зробленій від імені даній транзакції. Параметр у відповідь операції SAVE (а прямих параметрів, крім ідентифікатора транзакції, вона не вимагає) є ідентифікатор точки збереження. Цей ідентифікатор надалі може бути використаний як прямий параметр операції RESTORE, при виконанні якої проводиться відновлення бази даних по журналу, з використанням записів про її зміни від даної транзакції до того стану, в якому знаходилася база даних до моменту встановлення вказаної точки збереження. Крім того, по локальній інформації в оперативній пам'яті, прив'язаній до транзакції, відновлюється стан її сканів. Відкат на початок транзакції ініціюється також зверненням до операції RESTORE, але з вказівкою деякого приреченого ідентифікатора точки збереження.
При виконанні своїх транзакцій користувачі System R ізольовані один від іншого, тобто не відчувають того, що система функціонує в багатокористувацькому режимі. Це досягається за рахунок наявності в RSS механізму неявної синхронізації (більш повно це ми обговоримо в наступному підрозділі). Поки помітимо лише, що до кінця транзакції ніякі зміни бази даних, вироблені в межах цієї транзакції, не можуть бути використані в інших транзакціях (спроба використання таких даних приводить до тимчасових синхрозаційних блокувань цих транзакцій). При виконанні операції END TRANSACTION відбувається "фіксація" змін, вироблених в даній транзакції, тобто вони стають видимими в інших транзакціях. Реально це означає зняття синхронізаційних захоплень з об'єктів бази даних, що змінювалися в транзакції. З цього слідує, що після виконання END TRANSACTION неможливі індивідуальні відкати даної транзакції. RSS просто робить недійсним ідентифікатор даної транзакції, і після виконання операції закінчення транзакції відкидає всі операції з таким ідентифікатором.
Остання операція інтерфейсу RSS - операція явної синхронізації LOCK. Ця операція дозволяє встановити явне синхрозаційне захоплення на вказане відношення (параметром операції є ідентифікатор таблиці). Виконання операції LOCK гарантує, що ніяка інша транзакція до кінця даної не зможе змінити дане відношення (вставити в нього новий кортеж, видалити або модифікувати існуючий), якщо встановлене захоплення відношення в режимі читання, або навіть прочитати будь-який кортеж цього відношення, якщо встановлене захоплення в режимі зміни.
З всього, що говорилося раніше з приводу підходу до синхронізації в System R і відповідного розбиття системи на рівні, слідує нелогічність наявності цієї операції в інтерфейсі RSS. Насправді, логічно ця операція надмірна, тобто якби її не було, можна цілком реалізувати SQL на частині операцій, що залишилася. До викладу матеріалу наступного підрозділу про це важко говорити, але заздалегідь помітимо, що операція LOCK введена в інтерфейс RSS для можливості оптимізації виконання запитів. Справа в тому, що, як видно з опису інтерфейсу, він покортежний. Отже, і інформація для синхронізації носить досить вузький характер. У той же час на рівні SQL є більш повна інформація. Наприклад, якщо обробляється пропозиція SQL DELETE FROM EMP, то відомо, що будуть видалені всі кортежі вказаної таблиці. Зрозуміло, що як би не реалізовувався механізм синхронізації в RSS, в цьому випадку вигідніше повідомити відразу, що зміни торкаються всього відношення. Але знов забігаючи уперед, помітимо, що ситуації в компіляторі SQL, коли очевидна вигода від використання явної синхронізації, досить рідкі. Користуватися цим засобом можна тільки дуже обачно, тому що невиправдані захоплення таких великих об'єктів можуть різко обмежити міру асинхронності виконання транзакцій.
7.5. Синхронізація в System R
System R з самого початку задумувалася як багатокористувацька система, що забезпечує режим мультидоступу до баз даних. Тому питанням синхронізації доступу завжди приділялася дуже велика увага. Розробники System R сформулювали і частково вирішили багато проблем синхронізації, відповідні публікації давно стали класикою, і на них посилаються практично у всіх роботах, пов'язаних з синхронізацією в системах управління базами даних. Ми постараємося привести історичну ретроспектива рішень в області синхронізації в System R. Заздалегідь помітимо, що питання синхронізації знаходяться в тісному зв'язку з питаннями журналізації змін і відновлення стану бази даних.
Почнемо з розгляду цілей, якими керувалися розробники System R при виробленні свого підходу до синхронізації. Справа в тому, що початковою метою синхронізації операцій було не забезпечення ізольованості користувачів, а підтримка засобів забезпечення логічної цілісності баз даних. Як ми відмічали у введенні, логічна цілісність баз даних System R підтримується на основі наявності раніше сформульованих і записаних в каталогах бази даних обмежень цілісності. У кінці кожної транзакції або при виконанні явної пропозиції SQL перевіряється непорушення обмежень цілісності змінами, виробленими в даній транзакції. Якщо виявляється порушення обмежень цілісності, то за допомогою операції RSS RESTORE проводиться відкат транзакції, що порушила обмеження.
Для того, щоб можна було коректно виконати такий відкат, необхідно, щоб до кінця транзакції об'єкти бази даних, що змінювалися транзакцією, не могли змінюватися іншими транзакціями. У іншому випадку виникає так звана проблема втрачених змін. Дійсно, нехай транзакція 1 змінює деякий об'єкт бази даних A. Далі інша транзакція 2 також змінює об'єкт А, після чого проводиться відкат транзакції 1 (по причині, наприклад, порушення їй обмежень цілісності). Тоді при наступному читанні об'єкта А транзакція 2 побачить його