工作单元是维护受业务影响的对象的列表,并维护变化写入和并发问题的解决

大概的意思是说,对多个操作进行打包,记录对象上的所有变化,并在最后提交时一次性将所有变化通过系统事务写入数据库。

工作单元对并发的协调,是依靠聚合根上的乐观离线锁,以及数据库事务的并发控制能力来共同完成的。

Datatable是旧的工作单元,DataTable的AcceptChanges方法。所有修改就保存到数据库了新一代的工作单元DbContext成为数据访问的中心

尽晚打开,尽早释放

1、拦截器

实现类型 (implementationType) 或类型的任一方法标注了 UnitOfWork 特性的话,要继承IUnitOfWorkEnabled,这三种任一种情况都添加拦截器

IUnitOfWorkEnabled的派生:ApplicationService、BasicRepositoryBase<TEntity> 、DapperRepository<TDbContext>

  public override async Task InterceptAsync(IAbpMethodInvocation invocation)
        {
            if (!UnitOfWorkHelper.IsUnitOfWorkMethod(invocation.Method, out var unitOfWorkAttribute))
            {
                await invocation.ProceedAsync();
                return;
            }
            using (var uow = _unitOfWorkManager.Begin(CreateOptions(invocation, unitOfWorkAttribute)))
            {
                await invocation.ProceedAsync();
                await uow.CompleteAsync();
            }
        }

创建工作单元

最开始是null,新建一工作单元1,此时为当前工作单元,outer为null,再创建一个工作单元2,此工作单元是当前工作单元,outer为上一个工作单元1,而工作单元1的 outer为null

注意的是,如果工作单元属性为IsReserved、IsDisposed、IsCompleted,工作单元指向outer

当前工作单元不为空,并且不明确requiresNew》创建子工作单元

   public IUnitOfWork Begin(AbpUnitOfWorkOptions options, bool requiresNew = false)
        {
            Check.NotNull(options, nameof(options));

            var currentUow = Current;
            if (currentUow != null && !requiresNew)
            {
                return new ChildUnitOfWork(currentUow);
            }

            var unitOfWork = CreateNewUnitOfWork();
            unitOfWork.Initialize(options);

            return unitOfWork;
        }

private IUnitOfWork CreateNewUnitOfWork()
        {
            var scope = _serviceScopeFactory.CreateScope();
            try
            {
                var outerUow = _ambientUnitOfWork.UnitOfWork;
                var unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>();
                unitOfWork.SetOuter(outerUow);
                _ambientUnitOfWork.SetUnitOfWork(unitOfWork);
                unitOfWork.Disposed += (sender, args) =>
                {
                    _ambientUnitOfWork.SetUnitOfWork(outerUow);
                    scope.Dispose();
                };

                return unitOfWork;
            }
            catch
            {
                scope.Dispose();
                throw;
            }
        }
01-05 05:26