我在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();
} `
此代码工作正常,但问题是当我在事务处理期间访问表的数据(在事务期间访问的那些数据)时。这些表正由应用程序的其他部分访问。因此,当我尝试从表中读取数据时,它会引发异常。
答案 0 :(得分:15)
根据设计,SQL事务是ACID。特别是,“I”在这里伤害了你 - 这是设计以防止其他连接看到不一致的中间状态。
个人阅读连接可以选择使用NOLOCK
提示或READ UNCOMMITTED
隔离级别来忽略此规则,但听起来您想要的是写连接不带锁。好吧,那不会发生。
然而,可能的帮助是读者使用快照隔离,这可以在没有读者锁定的情况下实现隔离(通过查看,顾名思义,一点交易开始时的一致状态的时间分析)。
然而,IMO最好建议你看看:
第一个更简单。
一个简单的事实是:如果您采用长时间运行的事务处理大量数据,是您将导致问题。这就是不这样做的原因。系统运行正常。
答案 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 隔离级别是您正在寻找的。 p>
你说即使使用SNAPSHOT也没有按预期工作,独占锁正在发生,我可以理解,我有同样的问题。
确保您不仅在数据库选项上启用SNAPSHOT,而且还必须打开 READ COMMITTED SNAPSHOT 。
这是SQL Server 2008,所以仍然不确定这个答案是否会有所帮助:(
祝你好运!