Entity Framework 6 事务回滚 [英] Entity Framework 6 transaction rollback

查看:37
本文介绍了Entity Framework 6 事务回滚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 EF6,您有一个新事务,可以像这样使用:

With EF6 you have a new transaction which can be used like:

using (var context = new PostEntityContainer())
        {
            using (var dbcxtransaction = context.Database.BeginTransaction())
            {
                try
                {
                    PostInformation NewPost = new PostInformation()
                    {
                        PostId = 101,
                        Content = "This is my first Post related to Entity Model",
                        Title = "Transaction in EF 6 beta"
                    };
                    context.Post_Details.Add(NewPost);
                    context.SaveChanges();
                    PostAdditionalInformation PostInformation = new PostAdditionalInformation()
                    {
                        PostId = (101),
                        PostName = "Working With Transaction in Entity Model 6 Beta Version"
                    };

                    context.PostAddtional_Details.Add(PostInformation);
                    context.SaveChanges();

                    dbcxtransaction.Commit();
                }
                catch
                {
                    dbcxtransaction.Rollback();
                }
            }
        }

当事情横盘整理时,真的需要回滚吗?我很好奇,因为提交描述说:提交底层存储事务."

Is rollback actually needed when things go sideways? I'm curious because the Commit description says: "Commits the underlying store transaction."

而回滚描述说:回滚底层存储事务."

Whereas the Rollback description says: "Rolls back the underlying store transaction."

这让我感到好奇,因为在我看来,如果不调用 Commit,则不会存储先前执行的命令(这对我来说似乎合乎逻辑).但如果是这样,那又是什么原因要调用Rollback函数呢?在 EF5 中,我使用了没有回滚功能(只有一个 Complete)的 TransactionScope,这对我来说似乎是合乎逻辑的.由于 MS DTC 的原因,我不能再使用 TransactionScope,但我也不能像上面的例子那样使用 try catch(即,我只需要 Commit).

This makes me curious, because it looks to me that if Commit isn't called, the previously executed commands will not be stored (which seems logical to me). But if that is the case, what would the reason be to call the Rollback function? In EF5 I used TransactionScope which didn't have a Rollback function (only a Complete) which seemed logical to me. Due to MS DTC reasons I cannot use the TransactionScope anymore, but I also cannot use a try catch like the example above (i.e., I only need the Commit).

推荐答案

您不需要手动调用 Rollback,因为您正在使用 using 语句.

You don't need to call Rollback manually because you are using the using statement.

DbContextTransaction.Dispose 方法将在 using 块的末尾被调用.如果事务未成功提交(未调用或遇到异常),它将自动回滚事务.以下是SqlInternalTransaction.Dispose方法的源代码(DbContextTransaction.Dispose在使用SqlServer provider时最终会委托给它):

DbContextTransaction.Dispose method will be called in the end of the using block. And it will automatically rollback the transaction if the transaction is not successfully committed (not called or encountered exceptions). Following is the source code of SqlInternalTransaction.Dispose method (DbContextTransaction.Dispose will finally delegate to it when using SqlServer provider):

private void Dispose(bool disposing)
{
    // ...
    if (disposing && this._innerConnection != null)
    {
        this._disposing = true;
        this.Rollback();
    }
}

你看,它检查 _innerConnection 是否不为空,如果不是,回滚事务(如果提交,_innerConnection 将为空).让我们看看 Commit 做了什么:

You see, it checks if _innerConnection is not null, if not, rollback the transaction (if committed, _innerConnection will be null). Let's see what Commit does:

internal void Commit() 
{
    // Ignore many details here...

    this._innerConnection.ExecuteTransaction(...);

    if (!this.IsZombied && !this._innerConnection.IsYukonOrNewer)
    {
        // Zombie() method will set _innerConnection to null
        this.Zombie();
    }
    else
    {
        this.ZombieParent();
    }

    // Ignore many details here...
}

internal void Zombie()
{
    this.ZombieParent();

    SqlInternalConnection innerConnection = this._innerConnection;

    // Set the _innerConnection to null
    this._innerConnection = null;

    if (innerConnection != null)
    {
        innerConnection.DisconnectTransaction(this);
    }
}

这篇关于Entity Framework 6 事务回滚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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