Entity Framework 事务处理SaveChanges(false)

本文介绍了Entity Framework如何自动管理数据库事务,以及在特定场景下如何手动控制事务以确保数据一致性。通过使用TransactionScope和SaveChanges(false)方法,开发者可以在需要时实现自定义的事务处理逻辑,以应对复杂的业务需求。

Most of the time the Entity Framework (EF) can manage transactions for you.

Every time you Add an Entity, Delete an Entity, Change an Entity, Create a Relationship or Delete a Relationship in your .NET code, these changes are remembered by the EF, and when you call SaveChanges()these are converted to appropriate native SQL commands and executed in the database in a transaction.

Sometimes however you want to use your own transaction. Situations where this is useful include:

  • Working with an object context and attempting to put a message in a message queue within the same transaction.
  • Working with two object contexts simultaneously.
  • Etc etc etc… You get the idea.

In these situations you want the EF to use an ambient transaction (TransactionScope) but more importantly if something goes wrong outside of the EF, you want to be able to recover.

If you call SaveChanges() or SaveChanges(true),the EF simply assumes that if its work completes okay, everything is okay, so it will discard the changes it has been tracking, and wait for new changes.

Unfortunately though if something goes wrong somewhere else in the transaction, because the EF discarded the changes it was tracking, we can’t recover.

This is where SaveChanges(false) and AcceptAllChanges() come in.

SaveChanges(false) tells the EF to execute the necessary database commands, but hold on to the changes, so they can be replayed if necessary.

Now if the broader transaction fails you can retry the EF specific bits, with another call to SaveChanges(false). Alternatively you can walk through the state-manager to log what failed.

Once the broader transaction succeeds, you simply call AcceptAllChanges() manually, and the changes that were being tracked are discarded.

Typically pseudo-code for this is something 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();

    //If we get here it is save to accept all changes.
    context1.AcceptAllChanges();
    context2.AcceptAllChanges();

 

 

}

If you fall out of the using block because of an exception you can now potentially retry.

Make sense?

转载于:https://www.cnblogs.com/hyl8218/archive/2011/10/11/2206924.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值