DBMS如何解决事务中的冲突以及何时发生冲突?
例如,如果我有记录
id name value
1 N1 VAL1
我的隔离级别低于snapshot isolation
或serializable
(可重复读取或读取提交)
第一种情况。我有两笔交易。
第一笔交易T1
将name
字段更新为N2
update table set name = 'N2' where id = '1'
第二次交易T2
将字段value
更新为VAL2
。它在第一次交易之前完成。
update table set value = 'VAL2' where id = '1'
据我所知,两个交易都不应该发生冲突,因为它们会改变记录的不同字段。我是对的吗?或者,当事务T2
?
第二种情况。我有两笔交易。
第一笔交易T1
将name
字段更新为N2
。
update table set name = 'N2' where id = '1'
第二次交易T2
将name
字段更新为N3
。
update table set name = 'N3' where id = '1'
它再次在第一次交易之前完成。据我所知,它应该是一个冲突,因为第一个交易的name
字段的状态不像它在开始时那样。 那会发生什么?交易中止并重试?或者它会中止并回滚?
答案 0 :(得分:0)
您正在询问RDBMS如何实施' I' (隔离)部分ACID原则。 https://en.wikipedia.org/wiki/Isolation_(database_systems)
取决于RDBMS,但SQL Server使用锁定来实现它 (对于Oracle,Postgres,使用InnoDB但不是MyISAM的MySQL也应如此)。
交易按照收到的顺序处理 由于这个和锁定,在你的两个例子中,第二个事务都不可能在第一个事务之前完成。
第一个例子:
第一笔交易获取该行的独占锁定
第二个事务请求同一行的独占锁,但必须等待
第一个事务完成并释放其独占锁
现在名称=' N2',值=' VAL1'
第二个交易现在获得该行的独占锁定
第二个事务完成并释放其锁定
现在名称=' N2',值=' VAL2'
第二个例子:
第一笔交易获取该行的独占锁定
第二个事务请求同一行的独占锁,但必须等待
第一个事务完成并释放其独占锁
现在名字=' N2'
第二个交易现在获得该行的独占锁定
由于快照隔离,第二个事务将回滚,因为自事务开始以来,name的值已更改。它的锁被释放
现在名称=' N2'
此时重新运行第二个交易将导致名称成功更新为N3' (假设该行上没有其他并发事务)。