我试图让'SELECT'查询失败,如果它试图读取的记录被锁定 为了模拟它,我在UPDATE上添加了一个触发器,它睡眠了20秒然后在一个线程(Java应用程序)中我正在更新一个记录(oid = 53)而在另一个线程中我正在执行以下查询:
“SET STATEMENT max_statement_time = 1 FOR SELECT * FROM Jobs j WHERE j.oid = 53”。
(注意:由于我的mariadb服务器版本是10.2,我不能使用“SELECT ... NOWAIT”选项,必须使用“SET STATEMENT max_statement_time = 1 FOR ...。”而不是。
我希望SELECT会失败,因为记录处于UPDATE的中间并且应该被读/写锁定,但SELECT成功。
只有当我向SELECT查询添加'for update'时,查询才会失败。 (但这对我来说不是一个好选择)
我在这段时间检查了INNODB_LOCKS表,它是空的
在INNODB_TRX表中,我看到了具有隔离级别的事务 - REPEATABLE READ,但我不知道它是否与此相关。
任何想法,如何使SELECT失败而不进行更新'?
答案 0 :(得分:0)
通常一致(和脏)读取是非锁定的,它们只是读取某种快照,具体取决于事务隔离级别。如果要使读取等待并发事务完成,则需要将隔离级别设置为SERIALIZABLE
并关闭执行读取的连接中的自动提交。像
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET autocommit = 0;
SET STATEMENT max_statement_time=1 FOR ...
应该这样做。
旁注:我个人的偏好是使用innodb_lock_wait_timeout=1
代替max_statement_time=1
。两者都会使语句失败,但innodb_lock_wait_timeout
会导致错误代码更适合这种情况。