【问题标题】:What will be locked when I use mysql transaction?使用mysql事务时会锁定什么?
【发布时间】:2021-06-28 09:31:41
【问题描述】:

我对 mysql 事务感到困惑。我有一张如下表。

content  ip              status
aaa      null            wait
bbb      192.168.21.11   processing
ccc      null            wait
ddd      192.168.21.11   processing
eee      192.168.21.12   processing

我有两个进程在两台不同的机器上运行来处理这个表。他们每个人都在做以下操作。 (1)从表格中选择一个“等待”的内容 (2)统计每个ip上的内容,选择内容少的ip (3) 更新内容状态为处理中并设置ip列。

我曾经使用表锁来避免竞争条件,但它会导致死锁。所以现在我想改用事务。但是我对事务的锁定范围感到困惑。

当两个进程从表中选择等待内容并将其更新为处理时,我可以使用“for update”来避免竞争条件。但是我应该如何避免在计数和更新到处理时发生争用情况?在上面的例子中,两个进程都得到 1 和 192.168.21.12 并且都为进程选择它,那么这个 ip 上的内容将是 3。

事务中的所有查询是否都以原子方式执行,从而不会出现竞争条件?或者mysql只是锁定“select ... for update”和“commit”之间的行?

【问题讨论】:

  • 您在表定义中使用的是哪个引擎?
  • 我正在使用innodb。

标签: mysql sql


【解决方案1】:

在 MySQL Innodb 中,事务持有的锁在事务提交或回滚时被释放。在上述情况下,在步骤 1 中授予的锁将一直保持到事务完成。

事务不是原子运行的,如果它们不接触相同的记录,它们可以并发运行,否则,一个事务必须等待另一个事务释放锁。

关于语句会持有哪种锁,您可以参考Locks Set by Different SQL Statements in InnoDB了解更多详情

【讨论】:

  • 感谢您的回答。我有另一个问题。我看到文件说“开始事务”会自动设置autocommit=0,但我想知道如果“提交”自动设置autocommit=1。
  • 不,“start transaction”会开始一个新的事务,不影响“autocommit”的值。您可以使用 Mysql 客户端对其进行测试。见autocommit, Commit, and Rollback
  • 使用select @@autocommit;查看当前值。
猜你喜欢
  • 2023-03-18
  • 2012-07-23
  • 2011-12-30
  • 1970-01-01
  • 2011-08-29
  • 2011-01-25
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多