我已经尝试过明显的“SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED”,但是在更新正在进行时(当与某些复杂的更新事务同时运行时),我的简单存储过程在主键上执行 SELECT MAX 时仍然被阻止想要修改)——最终遇到死锁和锁定超时。
当然,必须有一种方法来保证非阻塞读取......我认为这就是 READ-UNCOMMITTED 的目的。但我错了……这是 MySQL 的 bug 吗?有解决方法吗?
我知道 READ-UNCOMMITTED 的所有危险和学术上不健全的特性,但这并不重要,对于我的特定应用程序,这里偶尔出现幻象或丢失行,这实际上没什么大不了的,但是由 READ-UNCOMMITTED 引起的延迟或错误读锁是一个更严重的问题。
数据库中的所有表都是InnoDB。服务器版本是5.0.67。平台是Linux 32位。
更新这是问题描述的简化“hello world”版本(我的实际查询太复杂且难看,无法发布):
控制台 1:
mysql> 创建表 t1(int 主键) engine=innodb; 查询正常,0 行受影响(0.20 秒) mysql> 插入 t1 值 (1),(2),(3); 查询正常,3 行受影响(0.03 秒) 记录:3 重复:0 警告:0 mysql> 开始事务; 查询正常,0 行受影响(0.00 秒) mysql> 插入 t1 值 (4); 查询正常,1 行受影响(0.01 秒) mysql> 更新 t1 设置 a=5,其中 a=4; 查询正常,1 行受影响(0.00 秒) 匹配的行:1 更改:1 警告:0
CONSOLE 2(在单独的窗口中,不要关闭CONSOLE 1)
mysql> 从 t1 中选择 max(a); +--------+ | 最大(a) | +--------+ | 3 | +--------+ 一组 1 行(0.00 秒) mysql> set @test = (从 t1 选择 max(a)); ERROR 1205 (HY000):超出锁定等待超时;尝试重新启动事务
终于明白了:
“这是 MySQL 的错误吗?” --> 是的,我称之为错误。其他人可能称之为限制或“陷阱”。我将其称为 BUG,因为显然,在没有锁的情况下检索此数据的理论基础和实际能力已通过主要语法解决方法的存在得到证明。
“有解决办法吗?” --> 是的。
重写这个
设置@test =(从t1中选择max(a));
作为这个
从 t1 中选择 max(a) 到 @test 中;
当另一个事务未运行时产生相同的结果;并在其他事务运行时产生预期结果(立即成功检索值,而不是因锁定而死亡)。
| 归档时间: |
|
| 查看次数: |
6459 次 |
| 最近记录: |