SQL Server - 防止丢失更新和死锁

时间:2014-11-29 19:37:40

标签: c# sql-server transactions

我正在开发一个项目,其中包含使用C#(.NET framework 4)开发的2个应用程序 -

  1. WCF服务(向客户公开)
  2. ASP.NET webforms应用程序(总公司使用)。
  3. 两个应用程序都可以从SQL Server 2005数据库中的常见“帐户”表中选择和更新行。帐户表中的每一行都有一个客户余额。

    两个应用程序中请求的业务逻辑涉及从“accounts”表中选择一行,根据余额进行一些处理,然后更新数据库中的余额。选择和更新余额之间的过程不能参与交易。

    我意识到可以在选择行和更新行之间,可以通过来自相同或不同应用程序的另一个请求来选择和更新行。

    我发现这个问题在下面的文章中描述。我指的是“丢失更新”的第二种情况。 http://www.codeproject.com/Articles/342248/Locks-and-Duration-of-Transactions-in-MS-SQL-Serve

      

    第二种情况是一个事务(事务A)读取a   记录并将值检索到局部变量中   记录将由另一个事务更新(事务B)。和   以后,事务A将使用中的值更新记录   局部变量。在这种情况下,事务B完成的更新可以   被视为“失去的更新”。

    我正在寻找一种方法来防止上述情况,并防止在同一行收到多个并发请求时平衡变为负数。应该一次只选择一个请求(来自任一应用程序)来更新行,以确保平衡一致。

    我正在考虑一旦一个请求选择了阻止访问行的行。根据我的研究,下面是我的观察。

    1. 隔离级别
    2. 使用'可重复读'隔离级别,2个事务可以选择一个公共行。

      我测试过这是打开2个SSMS窗口。在这两个窗口中,我启动了一个具有Repeatable读隔离级别的事务,然后在一个公共行上选择。我能够在每笔交易中选择一行。

      接下来,我尝试从每个事务更新同一行。这些陈述一直在运行几秒钟。然后,第一个事务的更新成功,而第二个事务的更新失败,并显示以下消息。

        

      错误1205:事务(进程ID)在锁资源上死锁   与另一个进程并被选为死锁受害者。重新运行   交易。

      因此,如果我使用带有Repeatable读取的事务,那么2个并发事务不应该更新同一行。 Sql server自动选择回滚1个事务。这是对的吗?

      但我还想通过仅允许单个事务选择特定行来避免死锁错误。

      1. ROWLOCK
      2. 我在Stackoverflow上找到了以下答案,其中提到使用ROWLOCK提示来防止死锁。 (见接受答案的评论)。

        Minimum transaction isolation level to avoid "Lost Updates"

        我启动了一个事务并使用了ROWLOCKUPDLOCK的select语句。然后在新的SSMS窗口中,我启动了另一个事务并尝试使用相同的select查询(具有相同的锁)。这次我无法选择行。该语句一直在新的SSMS窗口中运行。

        因此,使用Rowlock进行事务似乎阻塞了使用相同锁提示的select语句的行。

        如果有人能回答以下问题,我将不胜感激。

        1. 我对隔离级别和行锁的观察是否正确?

        2. 对于我描述的方案,我应该使用ROWLOCKUPDLOCK提示来阻止对行的访问吗?如果不是正确的方法是什么?

        3. 我打算在交易中放置我的选择和更新代码。事务中的第一个选择查询将使用ROWLOCKUPDLOCK提示。这将阻止另一个使用具有相同锁定的select的事务选择记录以检索同一行。

1 个答案:

答案 0 :(得分:0)

我建议使用SNAPSHOT的SQL隔离级别。与Oracles锁管理非常相似。

请参阅http://www.databasejournal.com/features/mssql/snapshot-isolation-level-in-sql-server-what-why-and-how-part-1.html

如果您的代码不是太复杂,您可以在不做任何更改的情况下实现此代码。请记住,某些可见性可能会受到影响(即脏读可能不会产生脏数据)

我觉得这个毯子系统比在整个地方使用查询提示更容易,更精确。

使用以下方式配置数据库:

SET ALLOW_SNAPSHOT_ISOLATION ON

然后使用它来为您的交易声明添加前缀:

SET TRANSACTION ISOLATION LEVEL SNAPSHOT