Если у вас есть такой код:
Something something = new Something();
BlahEntities b = new BlahEntities()
b.AddToSomethingSet(something);
b.SaveChanges();
как выполнить это добавление внутри транзакции?
Если у вас есть такой код:
Something something = new Something();
BlahEntities b = new BlahEntities()
b.AddToSomethingSet(something);
b.SaveChanges();
как выполнить это добавление внутри транзакции?
Вы можете поместить свой код в область транзакций
using(TransactionScope scope = new TransactionScope())
{
// Your code
scope.Complete(); // To commit.
}
TransactionScope находится в пространстве имен System.Transactions, которое находится в сборке с тем же именем (которое вам может потребоваться добавить вручную в ваш проект).
ObjectContext имеет свойство соединения, которое можно использовать для управления транзакциями.
using (var context = new BlahEntities())
using (var tx = context.BeginTransaction())
{
// do db stuff here...
tx.Commit();
}
В случае исключения транзакция будет отменена. Поскольку вызов BeginTransaction() требует и открывает соединение, имеет смысл обернуть вызов BeginTransaction, возможно, в метод расширения.
public static DbTransaction BeginTransaction(this ObjectContext context)
{
if (context.Connection.State != ConnectionState.Open)
{
context.Connection.Open();
}
return context.Connection.BeginTransaction();
}
Один из сценариев, в которых я считаю, что этот подход может быть полезен для TransactionScope, заключается в том, что вам нужно получить доступ к двум источникам данных и требовать только транзакционного контроля над одним из подключений. Я думаю, что в этом случае TransactionScope будет способствовать распределенной транзакции, которая может не потребоваться.
Я знаю, что для LINQ to SQL контекст данных создаст транзакцию для SubmitChanges(), если нет существующей внешней транзакции (TransactionScope - это "окружающая" транзакция). Я не видел, чтобы это было документировано для LINQ для Entities, но я видел поведение, чтобы предположить, что оно верно и для Entity Framework.
Итак, если вы используете один SubmitChanges() (L2SQL) или SaveChanges() (Linq to Entities) для всех связанных изменений, вы должны быть в порядке, не используя TransactionScope. Вам понадобится TransactionScope, когда
У меня были проблемы с вложенными TransactionScopes. Они должны работать, и простые тестовые примеры работают, но когда я попадаю в производственный код, "внутренняя" транзакция, похоже, является тем же объектом, что и внешняя транзакция. Симптомы включают ошибки, которые либо "совершены транзакцией, вы не можете использовать эту транзакцию больше", либо "этот объект транзакции уже удален". Ошибки возникают во внешней транзакции после выполнения внутренней транзакции.
using System.Transactions;
using (TransactionScope scope = new TransactionScope())
{
try
{
using(DataContext contextObject = new DataContext(ConnectionString))
{
contextObject.Connection.Open();
// First SaveChange method.
contextObject.SaveChanges();
// Second SaveChange method.
contextObject.SaveChanges();
//--continue to nth save changes
// If all execution successful
scope.Complete();
}
}
catch(Exception ex)
{
// If any exception is caught, roll back the entire transaction and end the scope.
scope.Dispose();
}
finally
{
// Close the opened connection
if (contextObject.Connection.State == ConnectionState.Open)
{
contextObject.Connection.Close();
}
}
}
Найдите приведенную ниже ссылку для подробного объяснения https://msdn.microsoft.com/en-us/data/dn456843.aspx
Во всех версиях Entity Framework всякий раз, когда вы выполняете SaveChanges() для вставки, обновления или удаления в базе данных, среда будет переносить эту операцию в транзакцию. Эта транзакция длится достаточно долго, чтобы выполнить операцию, а затем завершается. Когда вы выполняете другую такую операцию, запускается новая транзакция. Для новой версии платформы Entity Framework: 6.0 +
Подробнее здесь: EntityFramework и транзакция