Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server Sql Server中的xml列更新和锁定_Sql Server_Xml_Locking_Deadlock - Fatal编程技术网

Sql server Sql Server中的xml列更新和锁定

Sql server Sql Server中的xml列更新和锁定,sql-server,xml,locking,deadlock,Sql Server,Xml,Locking,Deadlock,我有一些windwos服务。他们从SQLServer获取xml列,并对其进行操作和更新 服务A-获取XML 服务B-获取XML 服务A-更新XML(它将丢失) 服务B-更新XML 我必须锁定行并使用下一个代码: SqlCommand cmdUpdate = new SqlCommand(); cmdUpdate.CommandText = "select MyXML from MyTable with(holdlock,rowlock) where id=@id";

我有一些windwos服务。他们从SQLServer获取xml列,并对其进行操作和更新

服务A-获取XML
服务B-获取XML
服务A-更新XML(它将丢失)
服务B-更新XML

我必须锁定行并使用下一个代码:

SqlCommand cmdUpdate = new SqlCommand();
            cmdUpdate.CommandText = "select MyXML from MyTable with(holdlock,rowlock) where id=@id";
            cmdUpdate.Parameters.AddWithValue("@id", id);

        using (SqlConnection conn = Helper.GetConnection())
        {
            cmdUpdate.Connection = conn;
            SqlTransaction ts = conn.BeginTransaction();
            cmdUpdate.Transaction = ts;
            XElement elem = XElement.Parse(cmdUpdate.ExecuteScalar().ToString());
            UpdateXElement(elem);
            cmdUpdate.Parameters.Clear();
            cmdUpdate.CommandText = "update MyTable set MyXML=@xml where id=@id";
            cmdUpdate.Parameters.AddWithValue("@id", id);
            cmdUpdate.Parameters.AddWithValue("@xml", elem.ToString());

            cmdUpdate.ExecuteNonQuery();
            ts.Commit();
        }
    }`
然后出现死锁

你有更好的办法来解决这个问题吗


谢谢

您描述的场景不是死锁。这是一个锁争用,换句话说,锁的确切用途是:

  • 服务A-获取XML
    -服务A锁定XML
  • 服务B-获取XML
    -服务B放置锁请求,等待服务A释放锁
  • 服务A-更新XML(它将丢失)
    -服务A应提交或回滚事务以释放锁。
  • 服务B-更新XML
    -服务B获取XML上的锁并更新它
  • 服务B
    将在步骤
    2
    3
    之间冻结

    这意味着您应该尽可能快地执行这些步骤

    更新:

    使用
    HOLDLOCK
    锁定事务中的行

    HOLDLOCK
    放置的共享锁与另一个共享锁兼容,但与
    update
    放置的更新锁不兼容

    下面是发生的情况:

  • 服务A
    将共享锁放置在
    第1行
    • 服务B
      将共享锁放置在
      第1行
    • 服务A
      尝试在
      行1
      上放置更新锁,该锁与
      服务B
      在步骤
      2
      上放置的共享锁不兼容<代码>服务A进入等待状态(同时仍持有步骤
      1上的共享锁)
    • 服务B
      尝试在
      行1
      上放置更新锁,该锁与
      服务A
      在步骤
      1
      上放置的共享锁不兼容<代码>服务B进入等待状态死锁
  • 这里没有必要在
    SELECT
    子句中放置共享锁。您应该将
    UPDLOCK
    放在
    SELECT
    子句中。这将使事务锁完全不兼容,任何一个事务在获取任何锁之前都必须等待其他事务的完成


    在这个场景中,死锁是不可能的。

    您描述的场景不是死锁。这是一个锁争用,换句话说,锁的确切用途是:

  • 服务A-获取XML
    -服务A锁定XML
  • 服务B-获取XML
    -服务B放置锁请求,等待服务A释放锁
  • 服务A-更新XML(它将丢失)
    -服务A应提交或回滚事务以释放锁。
  • 服务B-更新XML
    -服务B获取XML上的锁并更新它
  • 服务B
    将在步骤
    2
    3
    之间冻结

    这意味着您应该尽可能快地执行这些步骤

    更新:

    使用
    HOLDLOCK
    锁定事务中的行

    HOLDLOCK
    放置的共享锁与另一个共享锁兼容,但与
    update
    放置的更新锁不兼容

    下面是发生的情况:

  • 服务A
    将共享锁放置在
    第1行
    • 服务B
      将共享锁放置在
      第1行
    • 服务A
      尝试在
      行1
      上放置更新锁,该锁与
      服务B
      在步骤
      2
      上放置的共享锁不兼容<代码>服务A进入等待状态(同时仍持有步骤
      1上的共享锁)
    • 服务B
      尝试在
      行1
      上放置更新锁,该锁与
      服务A
      在步骤
      1
      上放置的共享锁不兼容<代码>服务B进入等待状态死锁
  • 这里没有必要在
    SELECT
    子句中放置共享锁。您应该将
    UPDLOCK
    放在
    SELECT
    子句中。这将使事务锁完全不兼容,任何一个事务在获取任何锁之前都必须等待其他事务的完成

    在这种情况下,死锁是不可能的。

    是的,但我有时会看到“事务(进程ID 108)在另一个进程的锁资源上被死锁,并被选为死锁受害者。请重新运行该事务。”异常。我的代码是否负责(因为锁)?在这种情况下如何防止死锁?谢谢,但我有时会看到“事务(进程ID 108)在另一个进程的锁资源上被死锁,并被选为死锁受害者。请重新运行该事务。”异常。我的代码是否负责(因为锁)?在这种情况下如何防止死锁?谢谢