加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

mysql – 使用LOCK TABLES回滚事务

发布时间:2020-12-11 23:49:32 所属栏目:MySql教程 来源:网络整理
导读:我有一个PHP / 5.2驱动的应用程序,它使用MySQL / 5.1下的事务,因此如果满足错误条件,它可以回滚多个插入.我有不同的可重用功能来插入不同类型的项目.到现在为止还挺好. 现在我需要对某些插入使用表锁定.正如官方手册所示,我使用SET autocommit = 0而不是STAR

我有一个PHP / 5.2驱动的应用程序,它使用MySQL / 5.1下的事务,因此如果满足错误条件,它可以回滚多个插入.我有不同的可重用功能来插入不同类型的项目.到现在为止还挺好.

现在我需要对某些插入使用表锁定.正如官方手册所示,我使用SET autocommit = 0而不是START TRANSACTION,因此LOCK TABLES不会发出隐式提交.并且,如文档所述,解锁表隐式提交任何活动事务:

> http://dev.mysql.com/doc/refman/5.1/en/lock-tables-and-transactions.html

问题在于:如果我只是避免使用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;
最佳答案 显然,LOCK TABLES无法修复以适应交易.解决方法是将其替换为SELECT …. FOR UPDATE.您不需要任何特殊语法(可以使用常规START TRANSACTION)并且它按预期工作:

START TRANSACTION;
SELECT COUNT(*) FROM foo FOR UPDATE; -- Lock issued
INSERT INTO foo (foo_name) VALUES ('John');
SELECT COUNT(*) FROM bar FOR UPDATE; -- Lock issued,no side effects
ROLLBACK; -- Rollback works as expected

请注意,COUNT(*)只是一个示例,您通常可以使用SELECT语句来获取您实际需要的数据;-)

(此信息由Frank Heikens提供.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读