Sql事务中的隔离级别

时间:2012-02-29 08:33:52

标签: c# sql sql-server-2005 transactions sqlconnection

我在c#中实现了SqlTransaction来开始,提交和回滚事务。一切都很顺利,但是在访问交易期间连接的那些表时我遇到了一些问题。 在交易期间我无法读取表格(那些在交易中的表格)。在搜索这个时,我发现它是由于独占锁而发生的。依次对该数据的任何后续选择都必须等待释放独占锁。然后,我已经完成了SqlTransaction提供的每个隔离级别,但它没有用。 因此,我需要在事务期间释放独占锁,以便其他用户可以访问该表并可以读取数据。 有没有办法实现这个目标? 提前谢谢。

这是我的交易的c#代码

try
{
  SqlTransaction transaction = null;                         
  using (SqlConnection connection=new SqlConnection(Connection.ConnectionString))
  {
       connection.Open();
       transaction=connection.BeginTransaction(IsolationLevel.Snapshot,"FaresheetTransaction");            
       //Here all transaction occurs   
       if (transaction.Connection != null)
       {     
               transaction.Commit();
               transaction.Dispose();
       } 
   }
}
catch (Exception ex)
{
   if (transaction.Connection != null)
       transaction.Rollback();
   transaction.Dispose();   
}   `                         

此代码工作正常,但问题是当我在事务处理期间访问表的数据(在事务期间访问的那些数据)时。这些表正由应用程序的其他部分访问。因此,当我尝试从表中读取数据时,它会引发异常。

4 个答案:

答案 0 :(得分:15)

根据设计,SQL事务是ACID。特别是,“I”在这里伤害了你 - 这是设计以防止其他连接看到不一致的中间状态。

个人阅读连接可以选择使用NOLOCK提示或READ UNCOMMITTED隔离级别来忽略此规则,但听起来您想要的是连接不带锁。好吧,那不会发生。

然而,可能的帮助是读者使用快照隔离,这可以在没有读者锁定的情况下实现隔离(通过查看,顾名思义,一点交易开始时的一致状态的时间分析)。

然而,IMO最好建议你看看:

  • 来自作家的多个更细粒度的交易
  • 在临时表中执行工作(数据的并行副本),然后在少量大量插入/更新/删除操作中将其合并到真实数据中,从而最大限度地缩短事务时间< / LI>

第一个更简单。

一个简单的事实是:如果您采用长时间运行的事务处理大量数据,您将导致问题。这就是不这样做的原因。系统运行正常。

答案 1 :(得分:3)

尝试在事务中执行读取并使用隔离级别READ UNCOMMITTED。这将阻止读取被锁定,但可能会产生无效结果:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED    
BEGIN TRANSACTION

SELECT * FROM Table

COMMIT TRANSACTION

有一种误解,处理交易/隔离级别只对写作有用,而实际上在阅读时同样重要。

答案 2 :(得分:2)

问题不在于写入数据库的程度,而在于读取值的级别。您正在尝试读取正在插入的值。尝试将您的选择查询更改为以下内容:

select * from your_table_with_inserts with (nolock)

然而,这个会覆盖当前事务的隔离级别,并且可能导致脏读。

所以问题是:如果您在所有查询中使用事务或仅插入/更新?

答案 3 :(得分:1)

@ AKASH88, SNAPSHOT 隔离级别是您正在寻找的。

你说即使使用SNAPSHOT也没有按预期工作,独占锁正在发生,我可以理解,我有同样的问题。

确保您不仅在数据库选项上启用SNAPSHOT,而且还必须打开 READ COMMITTED SNAPSHOT

enter image description here

这是SQL Server 2008,所以仍然不确定这个答案是否会有所帮助:(

祝你好运!