当前位置: 移动技术网 > IT编程>开发语言>.net > SmartSql使用教程(3)——SmartSql中的事务,及AOP的使用

SmartSql使用教程(3)——SmartSql中的事务,及AOP的使用

2019年06月18日  | 移动技术网IT编程  | 我要评论

一门3兄弟皆为航天院士,小镇大款,涞源

一、引言

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

 1 using system;
 2 using smartsql.dbsession;
 3 using smartsqlsamplechapterthree.entity;
 4 using smartsqlsamplechapterthree.repository;
 5 
 6 namespace smartsqlsamplechapterthree.domainservice
 7 {
 8     public class normaluserdomainservice : iuserdomainservice
 9     {
10         private const string default_avatar = "https://smartsql.net/logo.png";
11 
12         private readonly iuserrepository _userrepository;
13         private readonly iuserdetailrepository _userdetailrepository;
14         private readonly itransaction _transaction;
15 
16         public normaluserdomainservice(iuserrepository userrepository, iuserdetailrepository userdetailrepository, itransaction transaction)
17         {
18             _userrepository = userrepository;
19             _userdetailrepository = userdetailrepository;
20             _transaction = transaction;
21         }
22         
23         public user register(string loginname, string password, string nickname)
24         {
25             try
26             {
27                 _transaction.begintransaction();
28                 var user = new user
29                 {
30                     loginname = loginname,
31                     password = password,
32                     status = 1,
33                     createtime = datetime.now,
34                     modifiedtime = datetime.now
35                 };
36 
37                 user.id = _userrepository.insert(user);
38 
39                 _userdetailrepository.insert(new userdetail
40                 {
41                     userid = user.id,
42                     nickname = nickname,
43                     avatar = default_avatar,
44                     sex = null,
45                     createtime = datetime.now,
46                     modifiedtime = datetime.now
47                 });
48 
49                 _transaction.committransaction();
50                 return user;
51             }
52             catch
53             {
54                 _transaction.rollbacktransaction();
55                 throw;
56             }
57         }
58         
59         // use transaction on repository's sql mapper
60         public user registeruserepository(string loginname, string password, string nickname)
61         {
62             try
63             {
64                 _userrepository.sqlmapper.begintransaction();
65         
66                 var user = new user
67                 {
68                     loginname = loginname,
69                     password = password,
70                     status = 1,
71                     createtime = datetime.now,
72                     modifiedtime = datetime.now
73                 };
74         
75                 user.id = _userrepository.insert(user);
76         
77                 _userdetailrepository.insert(new userdetail
78                 {
79                     userid = user.id,
80                     nickname = nickname,
81                     avatar = default_avatar,
82                     sex = null,
83                     createtime = datetime.now,
84                     modifiedtime = datetime.now
85                 });
86         
87                 _userrepository.sqlmapper.committransaction();
88                 return user;
89             }
90             catch
91             {
92                 _userrepository.sqlmapper.rollbacktransaction();
93                 throw;
94             }
95         }
96     }
97 }

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

        public iserviceprovider configureservices(iservicecollection services)
        {  
            services.addmvc();

            /// 服务注册 begin

            /// 服务注册 end
            
            // autofac
            var builder = new containerbuilder();

            builder.registerdynamicproxy(config =>
            {
                config.interceptors
                      .addtyped<transactionattribute>(predicates.fornamespace("smartsqlsamplechapterthree.domainservice"));
            });
            builder.populate(services);

            var container = builder.build();
            return new autofacserviceprovider(container);
        }

  我在项目中很少使用autofac,所以对它的特性也不是很了解。只是按照文档做了最简单的实现,这里还要特别感谢交流群的小伙伴(qq群号:604762592)。是群里的一个小伙伴在使用autofac的时候分享了他的使用方式。

  这里在原生的基础上,创建一个autofac容器构建器,并在构建器中注册一个动态代理。然后在拦截器中加上transactionattribute就可以了。

 

三、结语

  以上就是smartsql中事务处理的一些方法,希望可以帮助到你。

 

示例代码链接在这里

  

下期预告:typehandler类型处理器使用讲解 and 如何自定义typehandler

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网