sql - 如何修复 "Snapshot isolation transaction aborted due to update conflict"?

标签 sql sql-server database deadlock transaction-isolation

我看到一条与事务隔离级别相关的错误消息。涉及两个表,第一个一个经常更新,事务隔离级别设置为SERIALIZABLE第二个一个在上有一个外键>第一个

插入或更新第二个表时出现问题。几个小时后我就会收到以下错误消息:

Snapshot isolation transaction aborted due to update conflict. You cannot use snapshot isolation to access table 'dbo.first' directly or indirectly in database 'DB' to update, delete, or insert the row that has been modified or deleted by another transaction. Retry the transaction or change the isolation level for the update/delete statement.

在插入或更新第二表时,我没有设置事务隔离级别,而且我运行了命令DBCC USEROPTIONS,它返回read_commissed。

最佳答案

第一:
看来,您没有使用 SERIALIZABLE ,但是快照隔离是在 MSSQL 2005 中引入的。这里有一篇文章可以帮助您了解其中的区别:
http://blogs.msdn.com/b/craigfr/archive/2007/05/16/serializable-vs-snapshot-isolation-level.aspx

=> 这是基于错误消息,但正如您在评论中再次解释的那样,编辑第二个表时会出现错误。

第二:
对于修改,MSSQL Server 总是尝试获取锁,并且由于第一个表上有锁(通过使用事务),因此升级到第二个表上的锁,因为(外键)操作失败。因此,每次修改实际上都会导致一次小型交易。

MSSQL 上的默认事务级别是 READ COMMITTED ,但是如果您打开选项 READ_COMMITTED_SNAPSHOT它将转换READ COMMITTEDSNAPSHOT每次使用READ COMMITTED就像交易。这会导致您收到错误消息。

准确地说,正如 VladV 指出的那样,它并没有真正使用 SNAPSHOT隔离级别,但是READ COMMITTED 使用行版本控制而不是锁定,但仅基于语句,其中 SNAPSHOT事务的基础上使用行版本控制。

要了解差异,请查看以下内容:
http://msdn.microsoft.com/en-us/library/ms345124(SQL.90).aspx

了解有关 READ_COMMITTED_SNAPSHOT 的更多信息,详细解释如下:
http://msdn.microsoft.com/en-us/library/tcbchxcb(VS.80).aspx
和这里: Default SQL Server IsolationLevel Changes

您看到的另一个原因SNAPSHOT如果您没有指定隔离,则使用隐式事务。打开此选项后,并且您实际上没有在修改语句上指定隔离级别(实际上您没有指定),MS SQL Server 将选择他认为正确的隔离级别。详细信息如下:
http://msdn.microsoft.com/en-us/library/ms188317(SQL.90).aspx

对于所有这些场景,解决方案都是相同的。

解决方案:
您需要按顺序执行操作,您可以通过专门使用 SERIALIZABLE 的事务来执行此操作。两个操作的隔离级别:插入/更新第一个操作时和插入/更新第二个操作时。
这样您就可以阻止相应的另一个,直到完成为止。

关于sql - 如何修复 "Snapshot isolation transaction aborted due to update conflict"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5102427/

相关文章:

php - 尝试从 PHP 连接数据库 MySQL(未成功)

html - 终极网站测试字符串

sql - Oracle PL SQL : using labels to get out of for loops

SQL - WHERE 中的 CASE 表达式

sql - Select 语句在表之间进行左连接,同时根据右表中的特定值过滤结果?

sql-server - 如何从 Azure SQL 数据库复制到本地 ubuntu 计算机?

asp.net - ASP.Net 与 SQL Server 中的数据安全

sql-server - 使用 t-sql 脚本启用/禁用 Sql Server 代理

mysql - 插入从表中选择一列

sql - @@IDENTITY 在 INSERT 语句之后总是返回 0