一、引言

  经过两章的铺垫,我们现在对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中

 NormalUserDomainService

  在这个类中,我实现了两次事务调用。在第一个方法中我们使用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中与原生相比,略微有一些不同。