English 中文(简体)
xml Column update and Locking in Sql Server
原标题:

I have a few windwos services. They get xml column from Sql server manipulate and update it.

Service A- Gets XML
Service B- Gets XML
Service A- Updates XML (it will be lost)
Service B- Updates XML

I must lock row and I use next Code:

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();
        }
    }`

then occurs Deadlocks.

Have you got a better idea, to solve this problem ?

Thanks

最佳回答

The scenario you are describing is not a deadlock. It s a lock contention, in other words, exactly what the locks are for:

  1. Service A- Gets XML - Service A locks XML
  2. Service B- Gets XML - Services B places lock request which waits for service A to release the lock
  3. Service A- Updates XML (it will be lost) - Service A should commit or rollback the transaction to release the lock.
  4. Service B- Updates XML - Service B acquires the lock on the XML and updates it

Service B will be frozen between steps 2 and 3.

This means you should perform these steps as fast as possible.

Update:

You use a HOLDLOCK to lock the row in a transaction.

HOLDLOCK places a shared lock which is compatible with another shared lock but not with update lock placed by UPDATE.

Here s what happens:

  1. Service A places a shared lock on row 1
    • Service B places a shared lock on row 1
    • Service A tries to place an update lock on row 1 which is not compatible with the shared lock placed by Service B on step 2. Service A enters wait state (while still holding a shared lock placed on step 1).
    • Service B tries to place an update lock on row 1 which is not compatible with the shared lock placed by Service A on step 1. Service B enters wait state. DEADLOCK.

There is no point in placing a shared lock in a SELECT clause here. You should place an UPDLOCK in a SELECT clause instead. This will make the transaction locks completely incompatible and either transaction will have to wait for completion of other transactions before acquiring any locks.

In this scenario, deadlocks are impossible.

问题回答

暂无回答




相关问题
Export tables from SQL Server to be imported to Oracle 10g

I m trying to export some tables from SQL Server 2005 and then create those tables and populate them in Oracle. I have about 10 tables, varying from 4 columns up to 25. I m not using any constraints/...

SQL server: Can NT accounts be mapped to SQL server accounts

In our database we have an SQL server account that has the correct roles to access some of the databases. We are now switching to windows authentication and I was wondering if we can create a NT user ...

SQL Server 2000, ADO 2.8, VB6

How to determine if a Transaction is active i.e. before issuing Begin Transaction I want to ensure that no previous transaction are open.. the platform is VB6, MS-SQL Server 2000 and ADO 2.8

热门标签