У меня есть сценарий, в котором, как мне кажется, мне нужно заблокировать таблицу против всех действий (чтение и запись). Я использую Propel 1.6.x и намерен написать небольшую дополнительную библиотеку для обработки блокировки.Библиотека блокировки базы данных с базой данных для PHP
My use case - это таблица версий, в которой есть первичный ключ (id, создатель, версия). Пара столбцов (id, creator) на самом деле является PK в другой таблице. Когда новая строка вставлена, MAX (версия) считывается в PHP-коде, а затем вставляется в класс row для последующего сохранения. Между максимумом и сохранением существует потенциал состояния гонки, когда другой процесс может получить одно и то же максимальное значение, и тогда, конечно, одна из вставок потерпит неудачу из-за неединственности.
Чтобы избежать необходимости замков, я бы предпочел использовать подзапрос для спасения, что-то вроде:
INSERT INTO
test_model_test_organiser_versionable
(id, creator, version)
VALUES (
3,
1,
(
SELECT COALESCE(MAX(version), 1)
FROM test_model_test_organiser_versionable
WHERE id = 3
AND creator = 1
)
);
Однако это не поддерживается в Propel, и если я делаю это через PDO I не будет (афайк) иметь способ узнать значение, данное части «версии» составного ПК.
Теперь у меня мог бы быть дополнительный автоинкрементный столбец, так как после вставки можно было бы считывать автоматически увеличивающееся значение, и, следовательно, я могу сделать повторный выбор в Propel. Но я бы хотел, чтобы избежать постороннего столбца, если я могу помочь ему, кажется, кажется менее элегантным, на мой взгляд.
Итак ... я чувствую, что обертывание max & Сохранение вызовов в блокировке - это путь. Это должно было бы заблокировать всю таблицу IMO и защититься от чтения, а также от записи (иначе последующий макс-вызов не будет ждать и, следовательно, приведет к отказу от неединственности снова).
Мне нужно это, чтобы работать со всеми платформами, поддерживаемыми Propel, поэтому - если нет лучшего подхода, который я должен принять - есть ли библиотека PHP, которая будет делать эту блокировку в отношении любой базы данных PDO? Если нет, я могу сделать это сам - но приятно, если кто-то еще провел тестирование осла-работы против множества dbs (настроил MSSQL Server? - нет спасибо :)
Приложение: Я обнаружил, что в PostgreSQL можно выполнить 'INSERT INTO x ... RETURNING my_column' - это исправить, но, к сожалению, не нейтрально! – halfer
Я написал класс для PostgreSQL, который блокирует таблицу, используя «LOCK test_model_test_organiser_versionable IN SHARE ROW EXCLUSIVE MODE» - и это, похоже, решает проблему (мне нужно будет найти эквиваленты для всех других платформ db). Однако ответы все же приветствуются. – halfer