我將記錄拉出數據庫,將其內容發佈到事務性MSMQ隊列,然後更新行以指示它已發佈。 Enqueing-and-Updating是在TransactionScope中發生的,它本身在讀取所有記錄的DataReader-讀取循環內部。即:讀取發生在TransactionScope的之外的。事情是這樣的:使用NOLOCK解決查詢/更新場景的好主意?
SqlConnection conn = new SqlConnection(ConnectionString);
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "GetUnpublishedEvents";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
SqlDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection
| System.Data.CommandBehavior.SingleResult);
while (reader.Read())
using (TransactionScope scope = new TransactionScope())
{
string ID = reader.GetString(0);
string data = reader.GetString(1);
SqlConnection updateConn = new SqlConnection(ConnectionString);
updateConn.Open();
SqlCommand updateCommand = updateConn.CreateCommand();
updateCommand.CommandText = "SetEventAsPublished";
updateCommand.CommandType = System.Data.CommandType.StoredProcedure;
updateCommand.Parameters.Add(new SqlParameter("@ID", ID));
updateCommand.ExecuteNonQuery();
updateConn.Close();
Message msg = new Message(data);
RaiseMessageArrived(msg);
scope.Complete();
}
reader.Close();
使用,直到我修改GetUnpublishedEvents
使用NOLOCK
失敗,超時異常存儲過程SetEventAsPublished
。我的問題是:這是一個好主意嗎?是否超時異常提示我應該以其他方式做這件事?
我知道NOLOCK
在SQL Server中相當於READUNCOMMITTED
。不過,我並不太擔心在這個應用程序中讀取未提交的數據,但是(它並不是首先插入到事務中)。
編輯:
存儲過程都是微不足道的。 GetUnpublishedEvents
就是:
SELECT id, data
FROM eventsTable WITH (NOLOCK)
WHERE data IS NOT NULL
AND published IS NULL;
雖然SetEventAsPublished
是:
UPDATE eventsTable
SET published = GETDATE()
WHERE ID = @ID;
第二個連接是必需的,因爲第一個連接與打開的DataReader綁定。 – 2011-03-21 15:01:38
您可以啓用MARS(多個活動結果集)來解決這個問題。 http://msdn.microsoft.com/en-us/library/yf1a7f4f(v=VS.80).aspx – 2011-03-21 15:28:37