在mysql事务期间锁定表

时间:2018-02-27 13:21:52

标签: mysql sql innodb

我正在用PHP运行几个mysql查询来更改几个表中的值。

基本上是这样的(简化的伪代码)

$amount = (SELECT amount FROM wallet WHERE id = 1);
$amount = somelongcomplicatedtask($amount);
(UPDATE wallet SET amount = $amount WHERE id = 23);

可以有许多脚本并行处理mysql数据库(写入/读取),我需要确保以下内容:

  • 如果其中一个查询失败,则返回到目前为止完成的所有工作(我可以使用TRANSACTIONS)
  • 当我使用表钱包(1和23)中的两行时,它们需要被锁定,因此任何想要读取或写入它们的进程(除了当前进程)都必须等待。 (锁定整个表也没关系,如果它不能仅锁定行)

该表使用InnoDB引擎。

问题是,如果我使用LOCK TABLES wallet WRITE锁定表格,然后运行START TRANSACTION,则会清除锁定。如果我首先运行START TRANSACTION然后我用LOCK TABLES锁定表,那么锁将COMMIT启动的事务......这两件事只是互相关闭,但我需要它们都是活动的在同一时间。

处理此问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

MySQL InnoDB存储引擎已经支持行级锁定。 在这种情况下,您必须对该特定行进行独占锁定,以便其他事务将等待,除非第一个事务释放其锁定。更多信息:InnoDB Locking Explained

答案 1 :(得分:0)

BEGIN;
SELECT ... FOR UPDATE;
longcomplicated...
UPDATE ...
COMMIT;

InnoDB的FOR UPDATE非常重要,因此它会将行锁定到UPDATE(实际上直到COMMIT)。

但是,如果BEGIN ... COMMIT花了太长时间",您将遇到其他问题。默认超时为50秒,这对于任何文明的事务设置来说都太长了。如果它太长,那么我们需要讨论其他锁定技术。

使用LOCK TABLES