sql-server - 可串行化事务死锁

标签 sql-server serialization transactions

文档说,可序列化事务一个接一个地执行。

但实际上这似乎并非事实。这是两笔几乎相等的交易,区别只是延迟了 15 秒。

#1:

set transaction isolation level serializable
go
begin transaction
if not exists (select * from articles where title like 'qwe')
begin
waitfor delay '00:00:15'
insert into articles (title) values ('qwe')
end
commit transaction go

#2:

set transaction isolation level serializable
go
begin transaction
if not exists (select * from articles where title like 'qwe')
begin
insert into articles (title) values ('asd')
end
commit transaction go

第二个事务在第一个事务开始后几秒钟后运行。

结果是死锁。第一个事务因

而终止
Transaction (Process ID 58) was deadlocked on 
lock resources with another process and has been chosen as the deadlock victim. 
Rerun the transaction.

原因。

结论,可序列化事务不是串行的?

最佳答案

可序列化事务不一定串行执行。

promise 只是事务只有在结果就像串行执行(以任何顺序)时才能提交。

满足此保证的锁定要求经常会导致死锁,其中一个事务需要回滚。您需要编写自己的重试逻辑来重新提交失败的查询。

参见The Serializable Isolation Level了解有关逻辑描述和实现之间差异的更多信息。

关于sql-server - 可串行化事务死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27347730/

相关文章:

sql - 如何按日期时间进行数据透视表或交叉表?

php - Boolean和Integer是序列化后的字符串

java - 在 @Configuration 类中的 Spring 中设置注释驱动的事务

paypal - 如何在拍卖风格的网络应用程序中进行 PayPal/Google Checkout?

asp.net-mvc - 如何在 .net MVC 中创建安全的每个 Web 请求事务?

sql - 使用 TOP 在 SELECT 中选择

c# - 使用 sum 和 group by 将 Sql Query 转换为 linq

sql - 在联接表中计数的最佳方法

java - 更改 Jackson 中的默认序列化行为

caching - SparkSQL序列化缓存