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

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

问题描述

我一直在调查交易,只要我将 false 传递给 SaveChanges() 然后调用 AcceptAllChanges,它们似乎会在 EF 中自行处理() 如果没有错误:

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?

在交易中途分配的任何索引列会发生什么情况?我想如果有人在我的记录变坏之前在我的记录之后添加了一条记录,那么这意味着将缺少 Identity 值.

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.

是否有任何理由在我的代码中使用标准的 TransactionScope 类?

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

推荐答案

大多数时候使用实体框架 SaveChanges() 就足够了.这会创建一个事务,或加入任何环境事务,并在该事务中完成所有必要的工作.

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.

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

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.

即像这样(坏):

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();
}

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

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();

}

虽然调用 SaveChanges(false) 将必要的命令发送到数据库,但上下文本身并没有改变,因此您可以在必要时再次执行此操作,或者您可以询问 ObjectStateManager(如果需要).

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.

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

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

请参阅我的 博文 了解更多.

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

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