Откат транзакций с помощью LOCK TABLES

У меня есть приложение, управляемое PHP / 5.2, которое использует транзакции в MySQL / 5.1, поэтому оно может откатить несколько вставок, если возникнет ошибка. У меня есть разные многоразовые функции для вставки разных типов элементов. Пока все хорошо.

Теперь мне нужно использовать блокировку таблицы для некоторых вставок. Как предлагается в официальном руководстве, я использую SET autocommit = 0 вместо START TRANSACTION , поэтому LOCK TABLES не вызывает неявной фиксации. И, как описано в документации, разблокировка таблиц неявно фиксирует любую активную транзакцию:

И здесь лежит проблема: если я просто избегаю UNLOCK TABLES , то второй вызов LOCK TABLES фиксирует ожидающие изменения!

Похоже, что единственный способ - выполнить все необходимые LOCK ТАБЛИЦЫ одним оператором. Это кошмар обслуживания.

Есть ли у этой проблемы разумное решение?

Вот небольшой тестовый сценарий:

DROP TABLE IF EXISTS test;

CREATE TABLE test (
    test_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    random_number INT(10) UNSIGNED NOT NULL,
    PRIMARY KEY (test_id)
)
COLLATE='utf8_spanish_ci'
ENGINE=InnoDB;


-- No table locking: everything's fine
START TRANSACTION;
INSERT INTO test (random_number) VALUES (ROUND(10000* RAND()));
SELECT * FROM TEST ORDER BY test_id;
ROLLBACK;
SELECT * FROM TEST ORDER BY test_id;



-- Table locking: everything's fine if I avoid START TRANSACTION
SET autocommit=0;
INSERT INTO test (random_number) VALUES (ROUND(10000* RAND()));
SELECT * FROM TEST ORDER BY test_id;
ROLLBACK;
SELECT * FROM TEST ORDER BY test_id;
SET autocommit=1;



-- Table locking: I cannot nest LOCK/UNLOCK blocks
SET autocommit=0;
LOCK TABLES test WRITE;
INSERT INTO test (random_number) VALUES (ROUND(10000* RAND()));
SELECT * FROM TEST ORDER BY test_id;
ROLLBACK;
UNLOCK TABLES; -- Implicit commit
SELECT * FROM TEST ORDER BY test_id;
SET autocommit=1;


-- Table locking: I cannot chain LOCK calls ether
SET autocommit=0;
LOCK TABLES test WRITE;
INSERT INTO test (random_number) VALUES (ROUND(10000* RAND()));
SELECT * FROM TEST ORDER BY test_id;
-- UNLOCK TABLES;
LOCK TABLES test WRITE; -- Implicit commit
INSERT INTO test (random_number) VALUES (ROUND(10000* RAND()));
SELECT * FROM TEST ORDER BY test_id;
-- UNLOCK TABLES;
ROLLBACK;
SELECT * FROM TEST ORDER BY test_id;
SET autocommit=1;

5
задан Álvaro González 31 January 2011 в 09:34
поделиться