【发布时间】:2011-03-21 22:47:17
【问题描述】:
我正在从数据库中提取记录,将其内容发布到事务性 MSMQ 队列,然后更新该行以表明它已发布。 Enqueing-and-Updating 发生在 TransactionScope 中,它本身位于遍历所有记录的 DataReader 读取循环内。即:读取发生在TransactionScope 的外部。像这样的:
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;
【问题讨论】:
标签: .net tsql transactionscope