实体框架 - DbContextTransaction.Rollback() 中的问题

2024-02-02

我使用连接数据库Entity Framework。我实现了一个联系人存储库来保存联系信息(示例存储库)。在上述类文件中,我声明了一个static property用于处理DBEntities (i.e., BLabsEntities)即“Context”并且还宣布了static property for DbContextTransaction.

在下面的代码中,我添加了一个 try catch 块来处理 Entity Framework 中的异常SaveContact()存储库方法。我发起了一个transaction在上述方法中开始保存联系人过程之前,我将异常数据添加到数据库表中dbo.Contact根据我的想法,它抛出了exception。在 Catch 块中我正在启动Rollback上述交易的过程,我正在尝试将异常消息插入到ErrorLog Table,但即使执行了回滚过程,Context 属性仍保留联系人信息。因此,在尝试将记录插入到中时,它再次在 catch 块中抛出异常dbo.ErrorLog Table。我添加了调试快照供您参考。

C# Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;

namespace EF_Sample
{
    public class ContactRepository
    {
        private static BLabsEntities _context;
        private static DbContextTransaction _dbTransaction;

        protected static BLabsEntities Context
        {
            get { return _context ?? (_context = new BLabsEntities()); }
        }

        protected static DbContextTransaction DBTransaction
        {
            get { return _dbTransaction; }
            set { _dbTransaction = value; }
        }

        public void SaveContact(Contact contact = null)
        {
            try
            {
                if (contact == null)
                {
                    contact = new Contact()
                    {
                        FirstName = null,
                        LastName = null
                    };
                }


                BeginTransaction();
                Context.Contacts.Add(contact);
                Context.SaveChanges();
            }
            catch (Exception ex)
            {
                CommitTransaction(false);

                BeginTransaction();
                ErrorLog error = new ErrorLog()
                {
                    Message = ex.Message
                };

                Context.ErrorLogs.Add(error);

                Context.SaveChanges();
            }
            finally
            {
                CommitTransaction();
            }
        }

        private void BeginTransaction()
        {
            DBTransaction = Context.Database.BeginTransaction();
        }

        private void CommitTransaction(bool flag = true)
        {
            try
            {
                if (flag)
                {
                    DBTransaction.Commit();
                }
                else
                {
                    DBTransaction.Rollback();
                }
            }
            catch (Exception Ex)
            {
                Console.WriteLine("Error: {0}", Ex.Message);
            }
        }
    }
}

调试快照:

异常于try Block:通过代码显式创建异常

异常于Catch Block:失败Rollback手术

数据库表结构:

请帮助我如何做Rollback操作成功到清除上下文更改.


实际的答案可能更简单:

https://github.com/aspnet/EntityFramework.Docs/issues/327 https://github.com/aspnet/EntityFramework.Docs/issues/327

在大多数情况下,对 dbContextTransaction.Rollback() 的显式调用是不必要的,因为在 using 块末尾处理事务将负责回滚。

如果 SQL Server 中发生足够严重的错误, 事务将自动回滚,并且调用 catch 块中的 dbContextTransaction.Rollback() 实际上会失败。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体框架 - DbContextTransaction.Rollback() 中的问题 的相关文章

随机推荐