即使第一次进行了更改,也要先尝试第二次交易才能看到同样的事情

时间:2017-07-04 22:47:14

标签: mysql sql transactions

我有以下两个交易(这是我正在尝试解决的旧考试问题)。我需要不使用commit,rollback或insert into 在事务A和B中获得相同的输出 我设法通过添加

来做到这一点
REPLACE INTO T
SELECT 10,10 FROM dual;

红色文字(标有“(1)”) 它工作但我想知道是否有任何其他方式,如改变隔离级别或做一些更棘手的事情? 此外,是否有来自事务B的命令我们可以删除它并仍然得到相同的结果? enter image description here https://i.imgur.com/Ba9jLOz.png

1 个答案:

答案 0 :(得分:0)

根据您的评论,您只能在红色虚线处发出命令。根据您的评论,我还假设innodb表引擎与默认的可重复读取隔离模式一起使用。

以上意味着无法使用更改事务隔离级别,因为显然您cannot change the isolation level of an ongoing transaction

这也意味着您需要一个语句,向表中添加一条记录,以补偿事务B运行时由事务A添加的id=5记录。这个问题排除了insert,所以这真的让你留下replace,因为它是唯一可以在表格中创建新记录的其他语句。

还有另一种偷偷摸摸的解决方案。发出

update t set b=1 where id=5;

并且计数将匹配。原因是一致快照适用于仅选择but not to changes to data。上述语句将使用id=5更新记录,从而将其带入快照:

  

数据库状态的快照适用于事务中的SELECT语句,不一定适用于DML语句。如果插入或修改某些行然后提交该事务,则从另一个并发REPEATABLE READ事务发出的DELETE或UPDATE语句可能会影响那些刚刚提交的行,即使会话无法查询它们。如果事务确实更新或删除了由其他事务提交的行,则这些更改将对当前事务可见。

此外,如果您在事务B中删除select之前的insert,则应该得到相同的结果,而不会在红色虚线上添加任何内容。一致快照由第一次读取建立。通过删除提到的select,将在事务A提交后建立快照,因此事务B可以看到它的更改。