ОК (я первоначальный спрашивающий), так что получается, что все это время у меня даже не было проклятой вещи.
Вот конечный код , который нужно запустить, чтобы включить режим моментального снимка и убедиться, что он включен.
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, указанная выше, соответствует IsolationLevel.ReadCommitted в .NET
Опция ALLOW_SNAPSHOT_ISOLATION выше соответствует IsolationLevel.Snapshot в .NET
Отличная статья о различных версиях
.NET Советы:
Похоже, Isolationlevel.ReadCommitted
разрешено в коде, даже если оно не включено базой данных. Предупреждение не выбрасывается. Так что сделайте себе одолжение и убедитесь, что он включен, прежде чем предположить, что он на 3 года, как я сделал!
Если вы используете C #, вам, вероятно, нужен ReadCommitted
IsolationLevel, а не Snapshot
- если вы не делаете записи в этой транзакции.
READ COMMITTED SNAPSHOT
делает оптимистичные чтения и пессимистичные записи. Напротив, SNAPSHOT
делает оптимистичные чтения и оптимистичные записи. (отсюда)
bool snapshotEnabled = true;
using (var t = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadCommitted
}))
{
using (var shipDB = new ShipperDBDataContext())
{
}
}
Кроме того, вы можете получить сообщение об ошибке «невозможность продвижения» транзакции. Поиск «продвижения» в Представление System.Transaction в .NET Framework 2.0 .
Если вы не делаете что-то особенное, например, подключаетесь к внешней базе данных (или второй базе данных), это может быть вызвано чем-то таким простым, как создание нового DataContext. У меня был кеш, который «раскручивал» свой собственный текст данных при инициализации, и он пытался перевести транзакцию в полностью распределенную.
Решение было простым:
using (var tran = new TransactionScope(TransactionScopeOption.Suppress))
{
using (var shipDB = new ShipperDBDataContext())
{
// initialize cache
}
}
См. Также Deadlocked
статья @ CodingHorror