В настоящее время я пытаюсь использовать вложенные области транзакций для доступа к БД по базе данных Azure SQL.
Я использую следующий код (.Net 4.5.1, мой код полностью асинхронный, ASP.Net MVC с EF6.1):
public async Task Test()
{
// In my actual code, the DbContext is injected within the constructor
// of my ASP.Net MVC Controller (thanks to IoC and dependency injection)
// The same DbContext instance is used for the whole HttpRequest
var context = new TestContext();
using (var t1 = StartTransactionForAsync())
{
using (var t2 = StartTransactionForAsync())
{
context.Users.Add(new User { Name = Guid.NewGuid().ToString() });
await context.SaveChangesAsync();
t2.Complete();
}
... // Some more code here
t1.Complete();
}
}
private static TransactionScope StartTransactionForAsync()
{
return new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted },
TransactionScopeAsyncFlowOption.Enabled);
}
Все в порядке, за исключением того, что TransactionScope
эскалируется в MSDTC, который (очевидно) не поддерживается Azure SQL Database. Поэтому я иногда получаю следующую ошибку:
Доступ к сети для Диспетчера распределенных транзакций (MSDTC) был отключен. Включите DTC для доступа к сети в безопасности конфигурации для MSDTC с использованием администраторов служб компонентов инструмент.
Я мог бы добавить Enlist=False
в мою строку соединения, но он сломал бы код выше, поскольку внутренняя транзакция все равно будет вставляться в базу данных, даже если внешний TransactionScope
располагается без Complete
.
Я нацелен на единую базу данных, используя один контекст Entity Framework для всего моего HttpRequest
, всегда с той же строкой соединения > .
Итак, мои вопросы:
- - это вложенные транзакции, поддерживаемые Azure SQL Database вообще?
- почему приведенный выше код иногда перерастает в MSDTC?
Официальная документация гласит:
База данных Microsoft Azure SQL не поддерживает распределенные транзакции, которые являются транзакциями, которые влияют на несколько ресурсов. Дополнительные сведения см. В разделе Распределенные транзакции (ADO.NET).
Начиная с версии 2.0, транзакции приложения могут быть автоматически продвигается к распределенным транзакциям. Это относится к приложения, использующие класс System.Data.SqlClient для выполнения операции базы данных в контексте System.Transactions сделка.
Продвижение транзакций происходит, когда вы открываете несколько подключений к различных серверов или баз данных в TransactionScope или когда вы зачислить несколько подключений в объекте System.Transactions, используя метод EnlistTransaction. Продвижение транзакций также происходит, когда вы открываете несколько одновременных подключений к одному и тому же серверу и базы данных либо в пределах одного TransactionScope, либо с помощью Метод EnlistTransaction.
Начиная с версии 3.5, транзакция не будет повышаться, если строки подключения для параллельных соединений - это точно одна и та же. Для получения дополнительной информации о транзакциях и избежании транзакций продвижение по службе, см. Интеграция System.Transactions с SQL Server (ADO.NET).
который не отвечает ни на один из моих вопросов.