Как использовать транзакции с datacontext
Можно ли использовать транзакции с datacontext, чтобы я мог откатить состояние контекста после ошибки? И если да, то как это работает?
Ответы
Ответ 1
DataContext по умолчанию запускает внешнюю транзакцию, так что это просто вопрос обеспечения транзакции в области видимости. Детали становятся главной проблемой:
- Какие параметры вам нужны (например, уровень изоляции)
- Вы хотите новую транзакцию или повторно использовать существующую транзакцию (например, для операции аудита/ведения журнала может потребоваться новая транзакция, чтобы ее можно было совершить, даже если общая бизнес-операция завершилась неудачей и, следовательно, внешняя транзакция откат).
Это упрощает некоторый код прототипа, настоящий код использует помощники для создания транзакций с политическими параметрами (одной из целей прототипа было изучение влияния этих параметров).
using (var trans = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions {
IsolationLevel = IsolationLevel.ReadCommitted
},
EnterpriseServicesInteropOption.Automatic)) {
// Perform operations using your DC, including submitting changes
if (allOK) {
trans.Complete();
}
}
Если Complete() не вызывается, транзакция будет отменена. Если есть область транзакции, содержащаяся в транзакции, то как внутренние, так и внешние транзакции должны быть заполнены для изменений в базе данных, которая должна быть зафиксирована.
Ответ 2
Я использую их в тестировании все время:)
try
{
dc.Connection.Open();
dc.Transaction = dc.Connection.BeginTransaction();
dc.SubmitChanges();
}
finally
{
dc.Transaction.Rollback();
}
UPDATE
Это будет ВСЕГДА откат после факта. Я использую это при тестировании.
Ответ 3
Что-то вроде этого, возможно:
try
{
using (TransactionScope scope = new TransactionScope())
{
//Do some stuff
//Submit changes, use ConflictMode to specify what to do
context.SubmitChanges(ConflictMode.ContinueOnConflict);
scope.Complete();
}
}
catch (ChangeConflictException cce)
{
//Exception, as the scope was not completed it will rollback
}
Ответ 4
Это не так просто, как метод TransactionScope, но, насколько я понимаю, это "правильный" способ сделать это для LINQ-to-SQL. Он не требует ссылки на System.Transactions.
dataContext.Connection.Open();
using (dataContext.Transaction = dataContext.Connection.BeginTransaction())
{
dataContext.SubmitChanges();
if (allOK)
{
dataContext.Transaction.Commit();
}
else
{
dataContext.Transaction.RollBack();
}
}
Конечно, RollBack требуется только в том случае, если вы намерены выполнять дополнительные операции с данными в процессе использования, иначе изменения будут автоматически отменены.
Ответ 5
Что-то вроде этого:
using (YourDatacontext m_DB = new YourDatacontext())
using (TransactionScope tran = new TransactionScope())
{
try
{
//make here the changes
m_DB.SubmitChanges();
tran.Complete();
}
catch (Exception ex)
{
Transaction.Current.Rollback();
}
}