简体   繁体   中英

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?

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:

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) ). 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 ):

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:

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. Same will happen if you do not commit it explicitly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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