Библиотека блокировки таблиц, не зависящая от базы данных, для PHP - PullRequest
0 голосов
/ 04 ноября 2011

У меня есть сценарий, в котором я думаю, что мне нужно заблокировать таблицу от всех действий (чтение и запись). Я использую Propel 1.6.x и намереваюсь написать небольшую дополнительную библиотеку для обработки блокировки.

Мой вариант использования - это таблица версий с первичным ключом (id, создатель, версия). Пара столбцов (id, создатель) на самом деле является PK на другой таблице. Когда вставляется новая строка, MAX (версия) читается в коде PHP, а затем вставляется в класс строки для последующего сохранения. Между максимальным и сохраненным значениями существует потенциал состояния гонки, при котором другой процесс мог бы получить такое же максимальное значение, и, конечно, одна из вставок потерпит неудачу из-за неединственности.

Чтобы избежать необходимости блокировок, я бы предпочел использовать подвыбор для сохранения, что-то вроде:

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, у меня не будет (afaik) способа обнаружить значение, присвоенное части «version» составного PK.

Теперь у меня может быть дополнительный автоинкрементный столбец, так как автоинкрементное значение может быть прочитано после вставки для поиска строки, и, следовательно, я могу сделать повторный выбор в Propel. Но я бы хотел избежать посторонней колонки, если смогу помочь - на мой взгляд, она выглядит не так элегантно.

Итак ... у меня такое ощущение, что завершение вызовов max & save в блокировку - это то, что нужно. Это должно было бы заблокировать всю таблицу IMO и защитить от чтения, а также от записи (в противном случае последующий максимальный вызов не будет ждать, и, следовательно, приведет к сбою неединственности снова).

Мне нужно, чтобы это работало со всеми платформами, поддерживаемыми Propel, поэтому - если нет лучшего подхода, который я должен использовать - есть ли библиотека PHP, которая будет выполнять эту блокировку для любой базы данных PDO? Если нет, то я могу сделать это сам - но было бы хорошо, если бы кто-то еще выполнил тестовую работу с различными dbs (настроить MSSQL Server? - нет, спасибо:)

1 Ответ

1 голос
/ 08 ноября 2011

Я пошел с полной блокировкой таблицы, пока MAX () и INSERT / UPDATE сделаны.Я обнаружил, что это работает:

  • MySQL: LOCK TABLES my_table WRITE
  • PostgreSQL: LOCK TABLE my_table IN SHARE ROW EXCLUSIVE MODE

Я планирую поискать и протестировать то же самое для Oracle, MSSQL и SQLite в свое время - но первые два, вероятно, наиболее популярны для проектов F / OSS.

...