简体   繁体   English

工作单元的行为+实体框架+事务,没有对异常的明确回滚

[英]Behavior of unit of work + entity framework + transaction without explicit rollback on exception

What happens when an transaction is started in a using then an exception happens but an rollback never occurs, because there is no try - catch rollback? 当在使用中启动事务然后发生异常但由于没有try-catch回滚而发生回滚时,会发生什么?

To illustrate the question more in detail see the following example: We use the unit of work pattern to generate the business transactions. 为了更详细地说明该问题,请参见以下示例:我们使用工作单元模式来生成业务交易。

The unit of work is encapsulated in a using. 工作单元被封装在一个使用中。 When starting the unit of work we might start a transaction (see example below.) 启动工作单元时,我们可能会启动事务(请参见下面的示例。)

//Starts a transaction
using (var uow = repositoryFactory.BeginUnitOfWork(true))
{
    //do stuff
    uow.Commit();
}

The transaction is started using the entity framework: 使用实体框架开始事务:

 CurrentContext.Database.BeginTransaction()

The question is now, what happens when an exception is thrown while "do stuff" the rollback is automatically triggered? 现在的问题是,在自动触发“执行操作”回滚时引发异常时会发生什么?

The repository factory Disposes the "CurrentContext" as follow: 存储库工厂按以下方式处理“ CurrentContext”:

public void Dispose()
{
    if (CurrentContext != null)
    {
        CurrentContext.Dispose();
    }
    CurrentContext = null;
    GC.SuppressFinalize(this);
}

What I have found was, that an open transaction will be closed if the connection to the database is closed (s. What happens if you don't commit transaction in a database (say SQL Server) ). 我发现的是,如果关闭与数据库的连接,则打开的事务将被关闭(例如, 如果您不在数据库中提交事务(例如SQL Server),将会发生什么情况 )。 The problem with that is, that when a connection is closed it's release back into the pool (s. https://msdn.microsoft.com/en-us/library/8xx3tyca(v=vs.110).aspx ): 问题在于,当连接关闭时,它会释放回池中( s。https ://msdn.microsoft.com/en-us/library/8xx3tyca( v=vs.110 ) .aspx ):

When a connection is closed, it is released back into the pool and into the appropriate subdivision based on its transaction context. 关闭连接后,它将根据其事务上下文释放回池中,并释放到相应的细分中。 Therefore, you can close the connection without generating an error, even though a distributed transaction is still pending. 因此,即使分布式事务仍处于挂起状态,您也可以关闭连接而不会产生错误。 This allows you to commit or abort the distributed transaction later. 这使您以后可以提交或中止分布式事务。

There is no try-catch block, but there is try-finally block and that is the using statement itself, which is roughly equivalent to the following: 没有try-catch块,但是有try-finally块,这就是using语句本身,大致等效于以下内容:

var uow = repositoryFactory.BeginUnitOfWork(true);
try
{
    //do stuff
    uow.Commit();
}
finally {
    // pseudo-code
    if (!uow.IsComplete) {
        uow.Rollback();
    }
}

So if exception happens - transaction will be rolled back, even without explicit try-catch block inside using. 因此,如果发生异常-事务将被回滚,即使内部没有显式的try-catch块也是如此。 Same will happen if you do not commit it explicitly. 如果您未明确提交,也会发生同样的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM