Передумови : я працюю над http://sqlfiddle.com (моїм сайтом), і намагаюся запобігти одному з можливих випадків зловживань. Я сподіваюся, що, запитуючи про проблему, яку я зараз вирішую, я ненавмисно не посилюю потенційне зловживання, але що ви можете зробити? Я довіряю вам, люди.
Я хотів би не допустити, щоб будь-який користувач видавав явні "фіксуючі" дзвінки в межах певного блоку транзакцій. З контексту SQL Fiddle блок транзакцій - це код, який виконується на правій панелі. В основному я перекидаю і виконую список команд SQL прямого тексту, і я хочу переконатися, що всі внесені ними зміни будуть повернуті в кінці партії. Зазвичай їх зміни повертаються назад, але іноді в тексті є явна заява "зафіксувати", і, звичайно, мій відкат не буде працювати. Ця явна фіксація дуже ймовірна від того, що користувач намагається зламати схему на SQL Fiddle, тому інші люди, що працюють над нею, побачать помилки.
Основний бажаний результат : Я хотів би відключити явні зобов’язання на рівні JDBC, якщо це можливо. Це тому, що я маю підтримувати декількох постачальників резервних даних бази даних, і, звичайно, кожен має свої химерності на низькому рівні.
Опція зворотного зв'язку : Якщо неможливо налаштувати JDBC для відключення явних комітетів, я б був відкритий для розпізнавання явних комітетів під час обробки пакету для кожного з наступних програм: SQL Server, Oracle, MySQL та PostgreSQL.
Для SQL Server я подумав про це рішення: проаналізуйте план запитів XML для оператора перед тим, як його виконати, і перевірте наявність запису, який відповідає цьому XPath:
//*[@StatementType="COMMIT TRANSACTION"]
Я думаю, що це буде добре працювати для SQL Server. Однак цей підхід не працює для інших типів БД. Виведення плану виконання файлів XML для явних комісій не посилається на те, що ви виконуєте оператор фіксації (а просто повторює вихідний план виконання з запитів, які він виконує). PostgreSQL і MySQL взагалі не дають жодного виводу плану виконання (XML або іншим чином) для явних комітетів.
Це дозволяє мені перевірити фактичну заяву на слово "зробити". Це спрацює, за винятком можливих варіацій:
declare @sql varchar(50)
set @sql = 'com' + 'mit'
exec(@sql);
Наведене вище є прикладом для SQL Server (який я міг би обійти), але я б припустив, що подібні речі будуть можливі для Oracle, MySQL та PostgreSQL. Я помиляюся в цьому припущенні? Можливо, вони не дозволять "динамічним" твердженням здійснювати? Сміливо використовуйте SQL Fiddle (бажано, щоб не зразок схеми чи хтось інший, ймовірно, працював над), щоб побачити, чи можете ви зробити щось подібне в Oracle, MySQL та PostgreSQL. Якщо ні, можливо, просте виявлення рядків може працювати для них.
Ще одна можливість
Мені припав ще один варіант - якщо ви знаєте спосіб встановити будь-яку з цих баз даних у режимі лише для читання, наприклад, коли в цьому режимі нічого не може бути зроблено, це теж може працювати. Мені потрібно все-таки дозволити запускати транзакції та виконувати код всередині них, до тих пір, поки нічого не вдасться зробити в цьому режимі. Це можливо?
Оновлення
Те, що я нещодавно дізнався - це насправді не проблема з PostgreSQL. Мабуть, зобов’язання, видані в блоці транзакцій, не застосовуватимуться, якщо той самий блок згодом отримає відкат (у Postgres). Тож ура для Postgres!
Завдяки посиланню Філа на посаду "SO", я думаю, що я можу використовувати ВІДХОДЖЕНОГО ПОСЛІДНО ВІДТВОРЕНОГО зламу для Oracle, щоб здійснити те, що я шукаю (помилка буде викинута, якщо буде видано комісію, але я можу обійтися цим). Це має стосуватися Oracle. (Я на мить подумав, що тут можуть працювати вкладені транзакції, але це не схоже на те, що Oracle підтримує вкладені транзакції? У всякому разі, я не міг знайти нічого, що працювало б таким чином).
Наразі ще не існує рішення для MySQL. Спробував за допомогою вкладених транзакцій, але, схоже, це не працює. Я серйозно замислююся над більш різкими підходами для MySQL, наприклад, як не дозволяти нічого, крім SELECTs з правого боку, або скидати / відтворювати БД після кожного запиту. Ні звук хороший, хоча.
Дозвіл
Отже, я реалізував описані рішення для SQL Server та Oracle, і як я вже згадував, це насправді не є проблемою для PostgreSQL. Для MySQL я зробив дещо невдалий крок обмеження панелі запитів лише до вибору операторів. DDL і DML для MySQL потрібно буде просто ввести на панелі схем (зліва). Я сподіваюся, що це не зламає занадто багато старих загадок, але я думаю, що це просто необхідно зробити для забезпечення узгодженості даних. Дякую!