Вимкнення явних комітетів у JDBC, виявлення їх у SQL або переведення в базу даних лише в режимі читання


12

Передумови : я працюю над 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 потрібно буде просто ввести на панелі схем (зліва). Я сподіваюся, що це не зламає занадто багато старих загадок, але я думаю, що це просто необхідно зробити для забезпечення узгодженості даних. Дякую!


Варто зазначити, що я також робив багато досліджень, розглядаючи тригери "попереднього вчинення". Здається, таких немає, тож, на жаль, це теж не є варіантом.
Джейк Фесель

2
Для Oracle це здається хорошою підлим способом лову коммітов: stackoverflow.com/a/6463800/790702 Те , що він не згадує про те , що ви повинні бути в змозі зловити порушення обмеження в коді теж, щоб зупинити 2 - й ситуації трапляються
Philᵀᴹ

@Phil єдина проблема в тому, що я не маю (і не дуже хочу) контролю над визначенням кожної з таблиць (ті визначені на лівій панелі). Так що відкладаються INITIALLY DEFERRED умова не буде там (а то й існує якийсь - то спосіб зробити це автоматично для всіх таблиць - слово через тригер системи , яка реагує на заяви створення таблиці Уф)
Джейк Feasel

1
@ NickChammas Мені потрібно відключити коміти, щоб я міг тримати схему (як визначено лівою бічною панеллю) у фіксованому стані. Можливо, будь-яка кількість людей, які пишуть запити проти однієї схеми, намагаються вирішити ту саму проблему. Щоб вони не заважали один одному, мені потрібно переконатися, що структура та дані не змінюються. Це здійснюється за допомогою відкатних транзакцій, але це не відбувається, якщо введено правий код.
Джейк Фесель

2
@RickJames DDL створює неявні коміти в MySQL та Oracle, але не в PostgreSQL або SQL Server. Механізми, які я впровадив після цієї публікації, вирішують це питання. Що стосується введення довільного SQL - у цьому вся суть!
Джейк Фесель

Відповіді:


3

Для Oracle це здається хорошим підлим способом ловити COMMIT:

/programming//a/6463800/790702

Те, що він не згадує, - це те, що ви повинні мати можливість вловлювати порушення обмеження у вашому коді, щоб зупинити 2-ю ситуацію.


Чудово, ще раз дякую Філ. Мені вдалося добре використати цю техніку для Oracle. Це змушує мене бажати, щоб інші бази даних підтримували відкладені обмеження.
Джейк Фесель

Не хвилюйтесь.
Зайдіть
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.