工作单元设计模式中的事务

本文关键字:事务 设计模式 单元 工作 | 更新日期: 2023-09-27 18:28:58

我很难理解工作单元的事务概念。我使用的代码如下:工人阶级的单位:

public class UnitOfWork : IDisposable
{
    private readonly DbContext _context;
    private bool disposed = false;
    public UnitOfWork()
    {
        _context = new ResultsContext();
    }
    public IRepository<T> GetRepository<T>() where T : class
    {
        return new Repository<T>(_context);
    }

    public virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                _context.Dispose();
            }
        }
        disposed = true;
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    public Study GetStudyWithAll(string studyUid)
    {
        ResultsContext context = _context as ResultsContext;
        return context.Studies.Where(c => c.StudyUid == studyUid)
                              .Include(s => s.Tasks.Select(t => t.Plugins))
                              .Include(s => s.Findings)
                              .Include(s => s.Patient).FirstOrDefault();
    }
    public void SaveChanges()
    {
        if (_context != null)
        {
            bool saved = false;
            do
            {
                try
                {
                    _context.SaveChanges();
                    saved = true;
                }
                catch (DbUpdateException ex)
                {
                    // Get the current entity values and the values in the database 
                    var entry = ex.Entries.Single();
                    //var currentValues = entry.CurrentValues;
                    switch (entry.State)
                    {
                        case System.Data.EntityState.Added:
                            // added on client, non in store - store wins
                            entry.State = System.Data.EntityState.Modified;
                            break;
                        case System.Data.EntityState.Deleted:
                            //deleted on client, modified in store
                            entry.Reload();
                            entry.State = System.Data.EntityState.Deleted;
                            break;
                        case System.Data.EntityState.Modified:
                            DbPropertyValues currentValues = entry.CurrentValues.Clone();
                            //Modified on client, Modified in store
                                entry.Reload();
                                entry.CurrentValues.SetValues(currentValues);
                            break;
                        default:
                            //For good luck
                            entry.Reload();
                            break;
                    }
                }
                catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
                {
                    Exception raise = dbEx;
                    foreach (var validationErrors in dbEx.EntityValidationErrors)
                    {
                        foreach (var validationError in validationErrors.ValidationErrors)
                        {
                            string message = string.Format("{0}:{1}",
                                validationErrors.Entry.Entity.ToString(),
                                validationError.ErrorMessage);
                            // raise a new exception nesting
                            // the current instance as InnerException
                            raise = new InvalidOperationException(message, raise);
                        }
                    }
                    throw raise;
                }
            } while (!saved);
        }
    }
    public DbContext Context
    {
        get { return _context; }
    }
} 

我使用它的方式:

using (var uow = new UnitOfWork())
{
   //////some stuff///
    uow.SaveChanges();
}

问题是:工作单元上下文是否等于事务,或者我需要添加:

using (TransactionScope transaction = new TransactionScope()) 

在它周围。

我知道saveChanges是用事务包装的,但我不知道的是:整个上下文是否用事务包装。我的意思是,我能确保我读取的数据(而不是保存或更新)在上下文的生命周期中没有更改吗?

工作单元设计模式中的事务

您的工作单元实现使用单个DbContext和对.SaveChanges()的单个调用。这本身就保证了所有的工作都是在一个简单的事务中完成的。参见,例如:

  • EF代码优先DBContext和事务
  • 处理事务(EF6以后):

在实体框架的所有版本中,每当您执行SaveChanges()来插入、更新或删除数据库时,框架都会将该操作包装在事务中。此事务只持续足够长的时间来执行操作,然后完成。当您执行另一个这样的操作时,将启动一个新的事务。

如果涉及多个.SaveChanges()甚至多个不同的DbContext实例,则只需要使用TransactionScope(请注意,在后一种情况下,它甚至可以触发分布式事务,这取决于正在启动的MSDTC服务)。

乐观并发

我之所以添加此注释是因为注释:为了避免锁定数据库,EF使用了一种称为乐观并发的机制,该机制基本上是检查在保存更改时读取后是否没有任何更改。有关更多信息,请参阅以下两个链接:

  • 乐观并发模式
  • 保存更改和管理并发

自从EF6以来,有很多方法可以启动自己的";古典的";具有所需隔离级别的事务。但这通常涉及锁定数据库的一部分,这可能会对应用程序性能产生有害影响。在大多数情况下,使用乐观并发要好得多。您会发现抛出并发异常的情况非常少,而且,正如链接中所解释的,它们是可以处理的。或者,您可以将存储过程用于特定任务,例如,减少在拥挤的电子商务网站上购买的产品的UnitsInStock。I.e使用一个存储过程来修改受保护交易中的库存,或者使用一个涉及隐式交易的UPDATE查询,而不是读取单位数量、减少单位数量并保存更改。