SmartSql使用教程(3)——SmartSql中的事务,及AOP的使用
一、引言
经过两章的铺垫,我们现在对SmartSql已经有了一定的了解,那么今天我们的主题是事务处理。事务处理是常用的一种特性,而SmartSql至少提供了两种使用事务的方法。一种是通过Repository(动态仓储)或者ITransaction的常规调用,一种是基于AOP提醒的动态代理方式。接下来我们一个个说。
上图是这一章的项目结构,这次的结构略微有点复杂,我一一解释。
项目结构分为3个部分,Api部分分成了3个.NetCore MVC项目,三个项目分别是常规调用;基于.NetCore原生DI的AOP调用;基于Autofac的AOP调用,AOP部分的区别只是在DI的配置部分。
DomainService也就是业务逻辑层,这个没什么好说的。
Data Access部分是实体与动态仓储,而在这一章中。我们的动态仓储项目有一个小的变动。先放图
通过图片可以看到,原来我们放在Api项目中的Map和Config都放到了动态仓储的项目。这个因为在当前项目中,我们有3个输出项目。如果每个项目中都写一套Maps就显得很多此一举。所以把它们统一的放到仓储类库里来,是一个很好的办法(虎哥提供)。注:别忘记把文件设置成始终复制哦
二、 常规使用
用法写在上面忽略了的DomainService中

在这个类中,我实现了两次事务调用。在第一个方法中我们使用ITransaction接口提供的方法,调用了Begin-Commit-Rollback的事务过程。
第二个方法中,我直接使用了Repository.SqlMap.BeginTransaction(),这是因为IRepository包含了一个ISqlMap,而ISqlMap同时继承了ITransaction。所以本质上这两种方式是等价的。
三、AOP
1. Nuget依赖
SmartSql有一个独立的Nuget包来支持AOP实现。名字就叫“SmartSql.AOP”
2. DomainService
使用了AOP后,我们的业务代码就可以干净很多。只需要在方法前加上[Transaction]特性就可以了。只要方法体中抛出异常,事务即会回滚。
[Transaction] public User Register(string loginName, string password, string nickname) { var user = new User { LoginName = loginName, Password = password, Status = 1, CreateTime = DateTime.Now, ModifiedTime = DateTime.Now }; user.Id = _userRepository.Insert(user); _userDetailRepository.Insert(new UserDetail { UserId = user.Id, Nickname = nickname, Avatar = DEFAULT_AVATAR, Sex = null, CreateTime = DateTime.Now, ModifiedTime = DateTime.Now }); return user; }
3. 原生配置
在Startup中稍稍修改一下ConfigureServices即可。
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc(); /// 服务注册 Begin /// 服务注册 End return services.BuildAspectInjectorProvider(); }
看一下上面代码你会发现,只需要为ConfigureServices方法加一个IServiceProvider返回值。并在方法最后加一句return就可以了。
4. Autofac配置
在Autofac中与原生相比,略微有一些不同。