由于选定行的更新冲突,快照隔离事务中止

Posted

技术标签:

【中文标题】由于选定行的更新冲突,快照隔离事务中止【英文标题】:Snapshot isolation transaction aborted due to update conflict for selected rows 【发布时间】:2019-01-25 09:26:51 【问题描述】:

快照隔离事务由于更新冲突而中止。你 不能使用快照隔离直接或间接访问表 在数据库中更新、删除或插入已被删除的行 被另一个事务修改或删除。重试交易或 更改更新/删除语句的隔离级别。

我读过这里提到的其他问题,但我的有点不同,我只是想用 select 语句读取一些数据,但如果这些选定的行在外部用另一个事务更新,那么我会遇到冲突错误。

如果我尝试使用LDPLOCK 提示,那么它会起作用,但会减慢它的速度。有什么解决办法吗?

下面的实际例子。

using (SqlConnection cn = new SqlConnection(connectionString))
                
                    await cn.OpenAsync();
                    using (SqlTransaction tran = cn.BeginTransaction(System.Data.IsolationLevel.Snapshot))
                    
            "select top 10 * from Employee where type = 1"
        
        

现在,如果我在上述事务提交完成之前还对员工表执行更新,则会引发上述错误。我不知道为什么,因为它只是选择语句。我阅读了微软的博客,说这会产生问题,但在任何地方都找不到解决方案。

update employee set IsActive = 1 where type = 1

【问题讨论】:

您的代码实际上根本不执行任何语句,也不会编译,但我认为这只是不好的解释。但是,您的情况尚不清楚:您是说 only 执行 SELECT 语句并且事务中没有其他任何内容出现更新冲突错误的代码吗?这与快照隔离的工作方式不符。你能把它减少到其他人可以重现的情况吗? 嗨,我刚刚添加了该代码作为示例,要复制此问题,您需要对表执行更新操作,并在可以在此事务范围之外更新的表上执行事务范围内的选择 @girishkolte 以什么隔离级别运行此查询update employee set IsActive = 1 where type = 1 我在有和没有快照隔离级别的情况下都尝试了更新员工查询,但它不起作用,如果我在两个地方都使用 readcommitted 那么它可以工作,但我需要它与快照隔离一起工作跨度> 【参考方案1】:

原来我无法对快照隔离事务中使用的表进行更新。我将表一分为二,将需要更新的列移到第二个表中,并且没有添加任何 FK 关系。它解决了问题。

【讨论】:

以上是关于由于选定行的更新冲突,快照隔离事务中止的主要内容,如果未能解决你的问题,请参考以下文章

为啥在另一个快照隔离事务中插入具有引用行的外键引用行的行会导致事务挂起?

精通Java事务编程-弱隔离级别之快照隔离和可重复读

精通Java事务编程-弱隔离级别之快照隔离和可重复读

读取提交的快照隔离和事务

数据库的快照隔离级别(Snapshot Isolation)

使用快照隔离防止 SQL 视图被冗长的删除/插入事务阻塞