MySQL锁定可用于简单的多项选择

时间:2018-10-24 13:54:45

标签: mysql

在存储过程中,我具有以下简单的两次选择序列:

SELECT * FROM mytable WHERE <conditions>;
SELECT id FROM mytable ORDER BY id DESC LIMIT 1;

其中 id mytable 的主键。

总体目的是从 mytable 中选择一些行(包括最新的行-即具有最大 id 值的行),然后选择第二行,获取同一表中最后/最新行的 id

问题:如何确保在第一选择和第二选择之间没有新记录插入?

我要使用:

TRANSACTION
select <1..> FOR UPDATE;
select <2..>;
COMMIT

但是这将始终有效并且有更好的方法吗?

还是可以做一些不同的事情来实现从第一个选择中获得最大的 id 值而无需第二个选择的目的?

1 个答案:

答案 0 :(得分:0)

如果您尚未更改隔离级别,则使用默认的REPEATABLE READ,它已经解决了此问题。

要检查您使用的隔离级别,可以执行以下查询:

SELECT @@global.tx_isolation, @@session.tx_isolation;

全局值是新创建的会话的默认值。会话值当然是您当前正在使用的值。

您可以使用以下方式为会话进行显式设置

SET SESSION tx_isolation='REPEATABLE-READ';

使用REPEATABLE-READ,您可以简单地执行以下操作:

START TRANSACTION;
SELECT * FROM mytable WHERE <conditions>;
SELECT id FROM mytable ORDER BY id DESC LIMIT 1;
COMMIT;

在您进行2次选择时,另一个会话在表中插入行时,该行将不会显示在您的事务中。

我在答案here中发布了有关隔离级别的更多详细信息。

如果要将两个查询合并为一个,可以执行以下操作:

SELECT m.*, s.maxid 
FROM mytable m 
CROSS JOIN (SELECT MAX(id) AS maxid FROM mytable) s 
WHERE <conditions>;