事务管理其实是应用服务层干的事。事务的协调管理都是由工作单元来负责的
所以,我们千万不能因为工作单元和仓储有联系就将它放置在领域层里面:事务的提供往往是由数据库管理程序来提供的,而这一类组件我们一般将它们放置在基础构架层,而领域层可以依赖于基础构架层,所以千万要注意,保持您的领域层足够干净,不要让其它的东西干扰它,也更不要将事务处理这类东西放到了您的领域层来。
第一种方法:当Web请求开始的时候创建一个连接,在所有的数据库操作时使用相同的连接,并且在请求结束时关闭或者释放该连接。这种方法很简单但是不够高效。
以事务的方式执行数据库操作已被认为是一种最佳实践。如果一个操作失败了,那么所有的操作都会回滚。因为一个事务可以锁定数据库中的一些行(甚至表),所以它必须是短暂存活的。
第二种方法:当需要时(仅在使用前)创建一个连接,使用后立即关闭。这是最有效的,但是到处创建或者释放连接是一项重复乏味的工作。
以下方法类型被认为是一个工作单元:
这边主要关心的是:某些情况下,我们需要创建一个新的工作单元作用域。
- using System.Threading.Tasks;
- using Volo.Abp.DependencyInjection;
- using Volo.Abp.Uow;
-
- namespace AbpDemo
- {
- public class MyService : ITransientDependency
- {
- private readonly IUnitOfWorkManager _unitOfWorkManager;
-
- public MyService(IUnitOfWorkManager unitOfWorkManager)
- {
- _unitOfWorkManager = unitOfWorkManager;
- }
-
- public virtual async Task FooAsync()
- {
- // 傻逼看这里
- using (var uow = _unitOfWorkManager.Begin(
- requiresNew: true, isTransactional: false
- ))
- {
- //...
-
- await uow.CompleteAsync();
- }
- }
- }
- }
Begin方法有以下可选参数:
requiresNew(bool): 设置为true可忽略周围的工作单元,并使用提供的选项启动新的UOW. 默认值为false. 如果为false,并且周围有UOW,则Begin方法实际上不会开始新的UOW,而是以静默方式参与现有的UOW.isTransactional(bool). 默认为false.isolationLevel(IsolationLevel?): 如果UOW是事务的,用于设置数据库事务的隔离级别. 如果未设置,则使用默认值.TimeOut(int?): 用于设置UOW的超时值. **默认值为null**并回退到默认配置值.
一般来说,不需要关心这些参数,只需要new 一个新的工作单元域就好了:
using (var uow = _unitOfWorkManager.Begin(new AbpUnitOfWorkOptions(), true)))