【问题标题】:Handle Lock Manually in SQL Server?在 SQL Server 中手动处理锁?
【发布时间】:2011-07-26 16:21:25
【问题描述】:

我是 SQL Server 的新手,但对选择/更新/删除和其他事务等简单的事情有相当的了解。我的应用程序面临死锁场景。我已经理解了这种情况,因为许多线程是并行的,试图运行一组更新操作。它不是单个更新,而是一组更新操作。

我知道这在我的应用程序中是无法避免的,因为很多人都想同时进行更新。所以我想要一个手动锁定系统。首先线程 1 应该检查手动锁是否可用,然后启动事务。同时,如果第二个线程请求锁,它应该很忙,因此第二个线程应该等待。一旦第一个完成,第二个应该获取锁并开始事务。

这只是我想到的一个逻辑。但我不知道如何在 SQL Server 中执行此操作。有没有可以帮助我的例子。如果您能给我一些对我有帮助的示例 sql 脚本或链接,请告诉我。感谢您的时间和帮助。

【问题讨论】:

    标签: sql sql-server sql-server-2005 sql-server-2008


    【解决方案1】:

    您的意思可能是“信号量”。也就是说,将 DML 的执行序列化为一次只能运行一个进程。

    这是在 SQL Server 中使用 sp_getapplock 的本机

    您可以配置第二个进程在调用 sp_getapplock 时等待或失败,也可以在“事务”模式下自行取消。

    【讨论】:

      【解决方案2】:

      您仍然很可能会遇到同样的情况。有一个基于您量身定制的锁的死锁。 SQL Server 在内部实现了一个非常健壮的锁定机制。你应该使用它。

      您遇到的问题是不同事务/线程以相互冲突的顺序访问(或修改)资源(表、索引等)。

      如果您创建自己的锁定机制,您最终可能会遇到同样的死锁。示例:

      1. 线程 1 在客户记录上创建锁
      2. 线程 2 在订单记录上创建锁
      3. 线程 1 尝试在订单记录上创建锁定(但由于第 2 步而无法继续)
      4. 线程 2 尝试在客户记录上创建锁定(但由于第 3 步而无法继续)

      瞧……死锁

      解决的办法是重构资源的访问方式,让记录总是按相同的顺序访问,问题就迎刃而解了。

      1. 线程 1 在客户记录上创建锁
      2. 线程 2 尝试在客户记录上创建锁定(但由于第 1 步而无法继续)
      3. 线程 1 在订单记录上创建锁
      4. 线程 1 完成交易并解锁订单和客户记录
      5. 线程 2 在客户记录上创建锁
      6. 线程 2 在订单记录上创建锁

      另外,请查看here,了解如何在单个表上发生锁定。

      【讨论】:

        【解决方案3】:

        您手动锁定系统听起来很有趣,但您需要注意它会牺牲并发性,这对于许多 OLTP 应用程序来说非常重要。

        像Oracle和SQL Server这样的Advance db在避免死锁方面做得很好,并为您提供解决死锁的工具,它可以帮助您杀死导致死锁的会话并让其他查询先完成它的工作。

        Microsoft 有可在此处找到的文档。 http://support.microsoft.com/kb/832524

        此外,还有许多其他原因可能导致死锁。你可以在这里找到一些例子。 how to solve deadlock problem?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-29
          • 1970-01-01
          • 2010-12-19
          • 1970-01-01
          相关资源
          最近更新 更多