Мое приложение (служба WCF) использует контексты данных LINQ, и недавно мы решили обернуть все в транзакцию. Кажется, работает довольно хорошо; каждый вызов в сервисе имеет свою собственную транзакцию, поэтому, если выдается исключение, все откатывается, и в базу данных не вносятся никакие изменения.
Однако у нас есть понятие «код супервизора», который можно создавать и использовать только один раз. Мы хотим, чтобы код супервизора был помечен как используемый, даже если ошибка произойдет позже в операции. Для меня это говорит о том, что я должен использовать внутреннюю транзакцию?
Итак, внутри моего SetToUsed
метода я ввел новую транзакцию, например, так:
public void SetToUsed(string code)
{
// security codes explicitly need their own transaction so that they will still be marked as having been used even if the outer transaction were to be rolled back due to error
using (var securityCodeTransaction = new TransactionScope(
TransactionScopeOption.RequiresNew,
new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadUncommitted
},
EnterpriseServicesInteropOption.Automatic))
{
var returnedItems = m_safetyCodeRepository.FindAll(sc => sc.safetyCode == code &&
sc.safetyCodeTypeId == (long)GetCodeType() &&
sc.isUsed == false);
foreach (var item in returnedItems)
{
item.isUsed = true;
m_safetyCodeRepository.SaveChanges(item);
}
securityCodeTransaction.Complete();
}
}
Однако это вызывает исключение: System.InvalidOperationException: Connection currently has transaction enlisted. Finish current transaction and retry.
Исключение выдается в строке FindAll
, которая является тонкой оболочкой для
dataContext.GetTable<tbSftSafetyCodes>().Where(exp).ToList()
Я что-то упускаю или поступаю по этому поводу совершенно неправильно?
Редактировать: я понял, что на самом деле мне не нужна транзакция для изменений кода руководителя как таковых.
Поэтому я изменил TransactionScopeOption
на TransactionScopeOption.Suppress
. Я все еще хотел бы знать, почему внутренняя транзакция с использованием TransactionScopeOption.RequiresNew
не сработала!