好的(我是最初的提问者)所以事实证明我一直没有启用该死的东西。
这里是 ultimate code 运行以启用快照模式并确保它已启用。
SELECT is_read_committed_snapshot_on, snapshot_isolation_state_desc,snapshot_isolation_state FROM sys.databases WHERE name='shipperdb'
ALTER DATABASE shipperdb SET allow_snapshot_isolation ON
ALTER DATABASE shipperdb SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE shipperdb SET read_committed_snapshot ON
ALTER DATABASE shipperdb SET MULTI_USER
SELECT is_read_committed_snapshot_on, snapshot_isolation_state_desc,snapshot_isolation_state FROM sys.databases WHERE name='shipperdb'
即使在连接处于活动状态时也能正常工作(大概你可以接受它们被踢出)。
您可以看到之前和之后的状态,这应该几乎立即运行。
重要提示:
上面的选项 READ_COMMITTED_SNAPSHOT 对应于 .NET 中的 IsolationLevel.ReadCommitted
上面的选项 ALLOW_SNAPSHOT_ISOLATION 对应 .NET 中的 IsolationLevel.Snapshot
Great article about different versioning
.NET 提示:
看起来Isolationlevel.ReadCommitted 在代码中是允许的,即使数据库未启用也是如此。不会引发任何警告。因此,请帮自己一个忙,并确保它已打开,然后再假设它像我一样使用了 3 年!!!
如果您使用 C#,您可能需要 ReadCommitted IsolationLevel 而不是 Snapshot - 除非您在此事务中执行写入操作。
READ COMMITTED SNAPSHOT 进行乐观读取和悲观写入。相比之下,SNAPSHOT 进行乐观读取和乐观写入。 (from here)
bool snapshotEnabled = true;
using (var t = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadCommitted
}))
{
using (var shipDB = new ShipperDBDataContext())
{
}
}
此外,您可能会收到有关“无法促进”交易的错误。在Introducing System.Transactions in the .NET Framework 2.0 中搜索“促销”。
除非您正在做一些特殊的事情,比如连接到外部数据库(或第二个数据库),否则像创建新 DataContext 这样简单的事情可能会导致这种情况。我有一个缓存,它在初始化时“启动”它自己的数据上下文,这试图将事务升级到一个完整的分布式事务。
解决方案很简单:
using (var tran = new TransactionScope(TransactionScopeOption.Suppress))
{
using (var shipDB = new ShipperDBDataContext())
{
// initialize cache
}
}
另见Deadlocked article by @CodingHorror