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中
using System;
using SmartSql.DbSession;
using SmartSqlSampleChapterThree.Entity;
using SmartSqlSampleChapterThree.Repository; namespace SmartSqlSampleChapterThree.DomainService
{
public class NormalUserDomainService : IUserDomainService
{
private const string DEFAULT_AVATAR = "https://smartsql.net/logo.png"; private readonly IUserRepository _userRepository;
private readonly IUserDetailRepository _userDetailRepository;
private readonly ITransaction _transaction; public NormalUserDomainService(IUserRepository userRepository, IUserDetailRepository userDetailRepository, ITransaction transaction)
{
_userRepository = userRepository;
_userDetailRepository = userDetailRepository;
_transaction = transaction;
} public User Register(string loginName, string password, string nickname)
{
try
{
_transaction.BeginTransaction();
var user = new User
{
LoginName = loginName,
Password = password,
Status = ,
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
}); _transaction.CommitTransaction();
return user;
}
catch
{
_transaction.RollbackTransaction();
throw;
}
} // use transaction on repository's sql mapper
public User RegisterUseRepository(string loginName, string password, string nickname)
{
try
{
_userRepository.SqlMapper.BeginTransaction(); var user = new User
{
LoginName = loginName,
Password = password,
Status = ,
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
}); _userRepository.SqlMapper.CommitTransaction();
return user;
}
catch
{
_userRepository.SqlMapper.RollbackTransaction();
throw;
}
}
}
}
NormalUserDomainService
在这个类中,我实现了两次事务调用。在第一个方法中我们使用ITransaction接口提供的方法,调用了Begin-Commit-Rollback的事务过程。
第二个方法中,我直接使用了Repository.SqlMap.BeginTransaction(),这是因为IRepository包含了一个ISqlMap,而ISqlMap同时继承了ITransaction。所以本质上这两种方式是等价的。
三、AOP
1. Nuget依赖
SmartSql有一个独立的Nuget包来支持AOP实现。名字就叫“SmartSql.AOP”
2. DomainService
使用了AOP后,我们的业务代码就可以干净很多。只需要在方法前加上[Transaction]特性就可以了。只要方法体中抛出异常,事务即会回滚。另外需要注意的地方是,AOP方法是需要用上virtual虚方法标识的。
[Transaction]
public virtual User Register(string loginName, string password, string nickname)
{
var user = new User { LoginName = loginName, Password = password, Status = , 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
SmartSql使用教程(3)——SmartSql中的事务,及AOP的使用的更多相关文章
- SmartSql使用教程(2)——使用动态代理实现CURD
一.引言 接着上一篇的教程,本章我们继续讲SmartSql.今天的主题是动态仓储. 老规矩,先上一个项目结构 从第二章开始.我们将原来的单一项目做了一个分离.方便之后的更新. 在这个结构中.原本上一章 ...
- SmartSql使用教程(1)——初探,建立一个简单的CURD接口服务
一.引言 最近SmartSql被正式引入到了NCC,借着这个契机写一个使用教程系列 二.SmartSql简介[摘自官方文档] 1. SmartSql是什么? SmartSql = MyBatis + ...
- Entity Framework入门教程(19)---EF中使用事务
EF中使用事务 这节介绍EF6中事务的使用.EF core中事务的使用方式和EF6中一模一样. 1.EF中的默认的事务 默认情况下,当我们执行一个SaveChanges()方法时就会新建了一个事务,然 ...
- SQL Server中的事务日志管理(9/9):监控事务日志
当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...
- Spring中@Transactional事务回滚
转载: Spring中@Transactional事务回滚 一.使用场景举例 在了解@Transactional怎么用之前我们必须要先知道@Transactional有什么用.下面举个栗子:比如一个部 ...
- 【MySQL】我这样分析MySQL中的事务,面试官对我刮目相看!!
写在前面 相信大部分小伙伴在面试过程中,只会针对面试官提出的表面问题来进行回答.其实不然,面试官问的每一个问题都是经过深思熟虑的,面试的时间相对来说也是短暂的,面试官不可能在很短的时间内就对你非常了解 ...
- Microsoft SQL Server中的事务与并发详解
本篇索引: 1.事务 2.锁定和阻塞 3.隔离级别 4.死锁 一.事务 1.1 事务的概念 事务是作为单个工作单元而执行的一系列操作,比如查询和修改数据等. 事务是数据库并发控制的基本单位,一条或者一 ...
- Redis系列之key操作命令与Redis中的事务详解(六)
序言 本篇主要目的有二: 1.展示所有数据类型中key的所有操作命令,以供大家学习,查阅,更深入的挖掘redis潜力. 2.掌握redis中的事务,让你的数据完整性一致性拥有更优的保障. redis命 ...
- SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因
原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...
随机推荐
- Spring Boot外部化配置实战解析
一.流程分析 1.1 入口程序 在 SpringApplication#run(String... args) 方法中,外部化配置关键流程分为以下四步 public ConfigurableAppli ...
- YARN和MapReduce的内存设置參考
怎样确定Yarn中容器Container,Mapreduce相关參数的内存设置,对于初始集群,由于不知道集群的类型(如cpu密集.内存密集)我们须要依据经验提供给我们一个參考配置值,来作为基础的配置. ...
- codevs1032
题目地址:http://codevs.cn/problem/1032/ 分析: 题目数据有错.这题过不了才正常. 我调了非常久可是就是有两个点过不去.于是我把数据下了下来,找到WA的第五个点和第七个点 ...
- TCP协议和socket API 学习笔记
本文转载至 http://blog.chinaunix.net/uid-16979052-id-3350958.html 分类: 原文地址:TCP协议和socket API 学习笔记 作者:gilb ...
- GCJ Qualification Round 2016 D题
这题就是找规律.小数据还是挺容易想的.大数据得再深入分析一下. 题意挺绕的. 其实就是字符串转换.字符串只能有两种字母,L或G.给定K和C,就能通过规则生成目标字符串. 那么,如果知道了K和C,以及目 ...
- 2018.11.06 生成器函数进阶&列表推导式&生成器表达式
1.生成器函数进阶 2.列表推导式 3.生成器表达式
- 区块链+AI将给区块链带来怎样的改变?
区块链和人工智能技术都是互联网时代最新.最热的技术,不仅可以改变我们生活,还能产生巨大的财富,为此国家大力支持发展,科技巨头们也纷纷布局.那区块链与人工智能结合,对区块链技术而言会产生什么样的化学反应 ...
- /dev/sda2 is mounted; will not make a filesystem here!
一定要记住,不可以在分区挂载之后再进行格式化!!在错误提示当中可以看出你的分区已经挂载了.先将这个分区卸载了再重新格式化:umount /dev/sda2mkfs.ext2 /dev/sda2这样就没 ...
- HDU3065 病毒侵袭持续中 —— AC自动机
题目链接:https://vjudge.net/problem/HDU-3065 病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- java反射技术实例
java反射技术实例1. [代码][Java]代码 package com.gufengxiachen.java.reflectiontest; public class Person {p ...