Я подозреваю, что не совсем понимаю, что происходит, или происходит что-то странное. (Первый случай более вероятен, я думаю.)
Большая картинка:
- Я пытаюсь заставить веб-службу выполнять определенные операции асинхронно, поскольку они могут занимать много времени, и я не хочу, чтобы клиент ждал завершения операций (просто время от времени запрашивайте результаты, чтобы увидеть, что операция Выполнено).
- Асинхронный код завернут в транзакцию — если что-то пойдет не так, я хочу иметь возможность откатить любые изменения.
- К сожалению, последним шагом асинхронного кода является вызов ДРУГОЙ службы, которая запрашивает ту же базу данных.
- Несмотря на то, что все это заключено в транзакцию Snapshot, последний шаг завершается ошибкой, поскольку служба не может прочитать данные из базы данных.
- В этом отношении, пока выполняется асинхронная операция, я также не могу выполнять простые операторы SELECT из базы данных.
Вот пример кода, который я сейчас использую для тестирования транзакций (сначала используя модель Entity Framework 5):
using (var transaction = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.RequiresNew, new System.Transactions.TransactionOptions() { IsolationLevel = System.Transactions.IsolationLevel.Snapshot }))
{
var db = new DataModelContainer();
Log test = new Log();
test.Message = "TEST";
test.Date = DateTime.UtcNow;
test.Details = "asd";
test.Type = "test";
test.StackTrace = "asd";
db.LogSet.Add(test);
db.SaveChanges();
using (var suppressed = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Suppress))
{
var newDb = new DataModelContainer();
var log = newDb.LogSet.ToArray(); //deadlock here... WHY?
}
test = db.LogSet.Where(l => l.Message == "TEST").Single();
db.LogSet.Remove(test);
db.SaveChanges();
transaction.Complete();
}
Код создает простую запись в журнале в базе данных (да, я сейчас играюсь, поэтому значения - мусор). Я настроил базу данных SQL, чтобы разрешить изоляцию моментальных снимков, и, насколько мне известно, чтение по-прежнему должно быть разрешено (они тестируются в этом коде с использованием новой подавленной транзакции и нового DataModelContainer
). Однако я не могу запросить LogSet
в подавленной транзакции или в SQL Management Studio - вся таблица заблокирована!
Итак... почему? Почему он заблокирован, если область транзакции определена как таковая? Я также пробовал другие уровни изоляции (например, ReadUncommited
), но все равно не могу запросить таблицу.
Может ли кто-нибудь дать объяснение такому поведению?
Serializable
), таких какReadUncommited
, и этот режим даже не требует включения изоляции моментальных снимков на сервере SQL! - person Shaamaan   schedule 24.01.2014