【问题标题】:wait to read a row when there is a lock on it -- transaction isolation当有锁时等待读取一行——事务隔离
【发布时间】:2015-02-24 13:39:08
【问题描述】:

我想锁定一个表行,以便对该行的任何其他读取操作将等到锁定被释放,并且我想避免锁定整个表。

我有下表(InnoDB)

CREATE TABLE account_balance (
    account INTEGER UNIQUE, 
    balance INTEGER NOT NULL, 
    PRIMARY KEY (account)
);

我执行下面的事务来获取一行的锁

START TRANSACTION;
SELECT balance FROM account_balance WHERE account = 1 FOR UPDATE;
SELECT SLEEP(10);
COMMIT;

我希望下面的查询等待锁被释放

SELECT balance FROM account_balance WHERE account = 1;

要做到这一点,我发现的唯一方法是按以下方式运行 SELECT

SET autocommit = 0; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SELECT ....;

它将等待锁被释放,但我应该在每个 SELECT 前面加上该表的自动提交和隔离级别设置。

有没有办法在表级别配置autocommit=0transaction-isolation = SERIALIZABLE ONLY

我知道我可以设置

[mysqld]
transaction-isolation = SERIALIZABLE
autocommit = 0

my.cnf,但我不想影响对其他表和架构进行的其他操作。

参考:

【问题讨论】:

  • 欢迎来到 Stack Overflow,感谢您提出有趣的问题。您使用哪种主机语言连接到 MySQL?
  • 嗨,奥利,感谢您的回复。将有多个客户端从该表中读取,并且它们可以用不同的语言(PHP 和 JS)编写。我正在寻找“服务器端”解决方案,因为我想强制执行它,而不管使用哪种语言来制作 SELECT。

标签: mysql transactions locking isolation-level transaction-isolation


【解决方案1】:

自动提交和事务隔离设置不与任何表关联,而是与 MySQL 的每个连接关联。

大多数语言绑定都有一个可直接调用的函数来启用或禁用自动提交。例如http://php.net/manual/en/mysqli.autocommit.php

您可以按照您的方式设置事务隔离级别。为连接设置后,它将保持设置状态。参见这个例子。 mySQL - Set isolation level using PHP's mysqli

在建立连接的代码之后立即放置此类模式设置代码通常是一种很好的做法,因此这些模式对于您的应用程序的其余部分是可预测的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    相关资源
    最近更新 更多