Я ищу способ выполнить запрос, когда TransactionScope жив, и игнорировать TransactionScope - в основном, я хочу выполнить этот конкретный запрос независимо от того, что.
Я использую сначала код EF и способ разработки приложения, новый контекст данных открывается много раз в течение одного вызова, каждый со своими собственными изменениями, и все они содержатся в пределах одного TransactionScope, который имеет Complete()
, называемый в конце, не допуская ошибок. Внутри контекста мы переопределили SaveChanges
, чтобы, если какое-либо исключение происходит на base.SaveChanges()
, мы можем поймать его и зайти в базу данных, прежде чем откатывать транзакцию.
Поскольку SaveChanges
происходит внутри транзакции, ведение журнала, очевидно, не происходит, поскольку оно относится к той же транзакции, что и исходный вызов. Я пытаюсь вообще игнорировать TransactionScope только для кода ведения журнала.
Вот несколько усеченных кодов:
// From the context
public override int SaveChanges() {
try {
return base.SaveChanges();
} catch (Exception ex) {
// Writes to the log table - I want this to run no matter what
LogRepo.Log(/*stuff to log from the context*/);
throw;
}
}
// Inside the business logic
public void DoSomething() {
try {
using (var scope = new TransactionScope()) {
using (var context = new FooContext()) {
// Do something
context.SaveChanges();
}
using (var context = new FooContext()) {
// Do something else
context.SaveChanges();
}
scope.Complete();
}
} catch (Exception ex) {
// scope.Complete is never called, so the transaction is rolled back
}
}
Я попытался использовать обычный ADO.NET вместо EF для ведения журнала, но все же те же результаты - он тоже откатывается.
Мне нужна обработка ошибок внутри SaveChanges
, потому что то, что я регистрирую, - это состояние сохраняемых объектов, поэтому я не могу просто переместить запись в другое место. Я мог бы создать сообщение, находясь внутри SaveChanges catch
, и выбросить его, и пусть DoSomething catch
занесет его в журнал, но есть десятки методов DoSomething
, и я бы скорее просто справился с этим в одном месте.