当我使用SNAPSHOT Isolation Level处理更新冲突问题时,似乎自动提交事务使用上次使用的隔离级别。
条件:ALLOW_SNAPSHOT_ISOLATION为ON,READ_COMMITTED_SNAPSHOT为OFF
步骤1:执行无交易的更新语句
using (var sqlconn = new SqlConnection("Data source=..."))
using (var sqlcmd = sqlconn.CreateCommand())
{
sqlconn.Open();
sqlcmd.CommandText = "Update ..."
sqlcmd.ExecuteNonQuery();
}
然后我查看sys.md_exec_sessions
,发现事务隔离级别为READCOMMITTED
。
步骤2:使用SNAPSHOT隔离级别的事务执行更新语句
using (var sqlconn = new SqlConnection("Data source=..."))
{
sqlconn.Open();
using (var sqltran = sqlconn.BeginTransaction(IsolationLevel.Snapshot))
using (var sqlcmd = sqlconn.CreateCommand())
{
sqlconn.Open();
sqlcmd.CommandText = "Update ..."
sqlcmd.ExecuteNonQuery();
}
}
隔离级别为Snapshot
,效果很好。
第3步:再次执行第1步
隔离级别为Snapshot
。
我希望第3步显示READCOMMITTED
因为READ_COMMITTED_SNAPSHOT为OFF。
我认为有两个想法,但我不能总结。
SNAPSHOT
任何想法都将受到赞赏。
谢谢,
答案 0 :(得分:1)
自动提交事务没有特定的隔离级别。它们使用最后为连接声明的隔离级别(或服务器默认值)。
不幸的是,面对连接池 1 ,您认为“新”连接实际上可能是一个重用的连接。因此,在某些情况下,您将选择使用与SQL Server默认值不同的隔离级别的连接(Read Committed)。
我的建议是 - 如果你在任何地方使用显式隔离级别,你还需要确保使用不同的连接字符串,或者你需要关闭 off 连接池,如果您不想明确设置隔离级别无处不在。我通常更喜欢第一个,因此您仍然可以从连接池中受益,但是为每个所需的隔离级别都有单独的池。
1 Connect Issue这似乎表明SQL Server 2014及更高版本可能会出现这种情况,也可能不成熟。