【问题标题】:Disable read/write to a table via SqlTransaction in .net?通过.net 中的 SqlTransaction 禁用对表的读/写?
【发布时间】:2011-02-16 23:55:11
【问题描述】:

如何在 .net 2.0 中使用 SqlTransaction,以便当我开始从表中读取数据时,该表被阻止以供其他人(其他程序)读取/写入该表?

如果 SqlTransaction 不是一个好的选择,那是什么?

【问题讨论】:

  • 嗨 - 我认为这应该默认发生,只要您的数据库写入在事务内并且数据库读取尊重这些事务,例如你不允许脏读/你没有使用 with(nolock) 提示...
  • 对不起。我重读了你的问题。如果您想在阅读时阻止,我认为您可能需要在您的选择上取消更新锁定,例如与(更新)。

标签: c# .net sql-server vb.net ado.net


【解决方案1】:

这应该通过在初始选择语句中使用可序列化事务和TABLOCKX 提示来允许。 TABLOCKX 应该对表进行独占锁定,这样其他人就不能使用该表,并且可序列化事务应该要求 HOLDLOCK,这意味着所有锁都保留到事务结束(您可以直接使用 HOLDLOCK)。

更新:我刚刚在 Management Studio 中测试了不同的场景,它 看起来你不需要 显式使用 Serializable 交易。使用 TABLOCKX 在任何 交易就够了。

请注意,这种方法可能会成为很大的瓶颈,因为只有一个事务可以在这样的表上操作 = 没有并发性。即使您阅读并使用了百万的单条记录,在您的事务结束之前,其他人也无法使用该表。

所以命令应该是这样的:

SELECT * FROM Table WITH (TABLOCKX) WHERE ...

要使用可序列化事务,您可以使用SqlTransaction

using (SqlConnection connection = new SqlConnection(connectionString))
{
  connection.Open();
  SqlTransaction transaction = connection.BeginTransaction(IsolationLevel.Serializable);

  try
  {
    ...
    transaction.Commit();
  }
  catch (Exception)
  {
    transaction.Rollback();
    ...
  }
}

或者System.Transactions.TransactionScope(默认隔离级别应该是Serializable)。

using (TransactionScope scope = new TransactionScope())
{
  using (SqlConnection connection = new SqlConnection(connectionString))
  {
    ...
  }
  scope.Complete();
}

【讨论】:

  • 您应该使用connection.BeginTransaction 方法,而不是使用SqlTransaction 的构造函数,因此您最终会得到一个基于您的连接的事务。否则,在连接上执行的任何操作都不会封装在事务中。
  • @Mark:谢谢。我用一些常见的 SqlTransaction 处理更正了它 - 我首先以与 TransactionScope 相同的方式编写它......我还删除了 var 构造,因为问题是关于 .NET 2.0。
猜你喜欢
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 2015-05-07
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
相关资源
最近更新 更多