使用事务或SaveChanges(false)和AcceptAllChanges()? [英] Using Transactions or SaveChanges(false) and AcceptAllChanges()?

查看:104
本文介绍了使用事务或SaveChanges(false)和AcceptAllChanges()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在调查交易,只要我通过 false SaveChanges()然后调用 AcceptAllChanges()如果没有错误:

 的SaveChanges(假); 
// ...
AcceptAllChanges();

如果事情变坏了怎么办?我不需要回滚,或者一旦我的方法超出范围,交易是否结束?



任何分配一半的indentiy列会发生什么通过交易?我假设如果有人在我的之前添加了一个记录,那么在我的错误之前,这意味着会有一个缺少的身份值。



有什么理由使用标准的 TransactionScope 我的代码中的类

解决方案

SaveChanges()就足够了。这将创建一个事务,或者在任何环境事务中进行访问,并在该事务中执行所有必要的工作。



有时,虽然 SaveChanges(false) + AcceptAllChanges()配对很有用。



最有用的地方是在两个不同的地方进行分布式事务上下文。



这样(坏):

  using(TransactionScope scope = new TransactionScope())
{
//使用context1
执行某些操作//使用context2

//保存并丢弃更改
context1.SaveChanges();

//保存并放弃更改
context2.SaveChanges();

//如果我们到这里的东西看起来不错。
scope.Complete();
}

如果 context1.SaveChanges()成功,但$ context2.SaveChanges()失败整个分布式事务中止。但不幸的是,实体框架已经丢弃了 context1 上的更改,因此您无法重播或有效地记录失败。



  using(TransactionScope scope = new TransactionScope())
{
//使用context1
执行某些操作//使用context2

//保存更改但不丢弃
context1.SaveChanges(false );

//保存更改但不丢弃
context2.SaveChanges(false);

//如果我们到这里的东西看起来不错。
scope.Complete();
context1.AcceptAllChanges();
context2.AcceptAllChanges();

}

虽然调用 SaveChanges( false)将必要的命令发送到数据库,上下文本身不会更改,因此如果需要,可以重新执行,或者可以询问 ObjectStateManager 如果你想要的话。



这意味着如果事务实际上抛出一个异常,你可以通过重新尝试或记录每个上下文的状态来补偿 ObjectStateManager



请参阅我的 博客文章了解更多。 / p>

I have been investigating transactions and it appears that they take care of themselves in EF as long as I pass false to SaveChanges() and then call AcceptAllChanges() if there are no errors:

SaveChanges(false);
// ...
AcceptAllChanges();

What if something goes bad? don't I have to rollback or, as soon as my method goes out of scope, is the transaction ended?

What happens to any indentiy columns that were assigned half way through the transaction? I presume if somebody else added a record after mine before mine went bad then this means there will be a missing Identity value.

Is there any reason to use the standard TransactionScope class in my code?

解决方案

With the Entity Framework most of the time SaveChanges() is sufficient. This creates a transaction, or enlists in any ambient transaction, and does all the necessary work in that transaction.

Sometimes though the SaveChanges(false) + AcceptAllChanges() pairing is useful.

The most useful place for this is in situations where you want to do a distributed transaction across two different Contexts.

I.e. something like this (bad):

using (TransactionScope scope = new TransactionScope())
{
    //Do something with context1
    //Do something with context2

    //Save and discard changes
    context1.SaveChanges();

    //Save and discard changes
    context2.SaveChanges();

    //if we get here things are looking good.
    scope.Complete();
}

If context1.SaveChanges() succeeds but context2.SaveChanges() fails the whole distributed transaction is aborted. But unfortunately the Entity Framework has already discarded the changes on context1, so you can't replay or effectively log the failure.

But if you change your code to look like this:

using (TransactionScope scope = new TransactionScope())
{
    //Do something with context1
    //Do something with context2

    //Save Changes but don't discard yet
    context1.SaveChanges(false);

    //Save Changes but don't discard yet
    context2.SaveChanges(false);

    //if we get here things are looking good.
    scope.Complete();
    context1.AcceptAllChanges();
    context2.AcceptAllChanges();

}

While the call to SaveChanges(false) sends the necessary commands to the database, the context itself is not changed, so you can do it again if necessary, or you can interrogate the ObjectStateManager if you want.

This means if the transaction actually throws an exception you can compensate, by either re-trying or logging state of each contexts ObjectStateManager somewhere.

See my blog post for more.

这篇关于使用事务或SaveChanges(false)和AcceptAllChanges()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆