Sql server 锁定提示MS-SQL Server、Slick和Scala

Sql server 锁定提示MS-SQL Server、Slick和Scala,sql-server,scala,slick,Sql Server,Scala,Slick,我正在尝试在我的应用程序中运行以下查询。有人能解释一下如果两个线程尝试选择同一行会发生什么情况,因为在下面的所有提示中都允许选择。我们在事务中看到很多死锁,它首先获取这个锁并执行一些操作。谢谢 select a, b, c, d, created_time, updated_time from lock_table with (ROWLOCK,UPDLOCK,HOLDLOCK) where a = $a

我正在尝试在我的应用程序中运行以下查询。有人能解释一下如果两个线程尝试选择同一行会发生什么情况,因为在下面的所有提示中都允许选择。我们在事务中看到很多死锁,它首先获取这个锁并执行一些操作。谢谢

select  a, b, c, d, created_time, updated_time
          from lock_table
              with (ROWLOCK,UPDLOCK,HOLDLOCK)
               where a = $a
               AND b = $b
               AND c = $c
               AND d = $d.as[LockTableDetails]
有人能解释一下如果两个线程尝试选择同一行会发生什么吗

假定

  • 这两个会话在此语句之前都已开始
  • 两个会话提供完全相同的参数值 及
  • 两个会话都使用读取相同索引的查询计划
  • 第一个会话将在查询读取的索引的每一行上获取一个更新(U)锁(如果没有匹配的行,则可能获取一个范围锁)。这些锁将在事务期间保持,第二个会话将被阻塞

    如果您在这里看到意外的并发执行,可能是因为您没有使用参数,而是使用Scala字符串插值。当您将字符串粘贴到SQL查询中时,这两个会话将发送不同的查询,这些查询将获得不同的执行计划,锁定不同的索引并进入死锁状态

    查询应使用参数,例如:

    select  a, b, c, d, created_time, updated_time
              from lock_table
                  with (ROWLOCK,UPDLOCK,HOLDLOCK)
                   where a = @a
                   AND b = @b
                   AND c = @c
                   AND d = @d.as[LockTableDetails]
    
    并使用。然后会话将实际执行相同的查询,并将获得相同的执行计划


    如果这不能修复死锁,请发布死锁XML和有关并发事务的其他详细信息。

    我使用sql interpolator。因此,代码看起来有点像:
    sql”““选择a、b、c、d,创建时间,从锁表中更新时间(ROWLOCK、UPDLOCK、HOLDLOCK),其中a=$a和b=$b,c=$c和d=$d”“”。如[LockTableDetails]
    然后发布死锁XML。它将显示是否发生了参数替换,以及死锁的原因。已解决该问题。表上定义的索引太多,因此插入速度较慢。因此,不应该在同一页面上停留很长时间的数据会留在那里,来自应用程序不同线程的select查询会导致死锁。