本文源码 github地址:知了一笑 https://github.com/cicadasmile/spring-boot-base
1、事务基本概念
一组业务操作abcd,要么全部成功,要么全部不成功。
2、特性:acid
原子性:整体
一致性:完成
隔离性:并发
持久性:结果
3、隔离问题
脏读:一个事务读到另一个事务没有提交的数据
不可重复读:一个事务读到另一个事务已提交的数据(update)
虚读(幻读):一个事务读到另一个事务已提交的数据(insert)
4、隔离级别
read uncommitted:读未提交。
read committed:读已提交。解决脏读。
repeatable read:可重复读。解决:脏读、不可重复读。
serializable :串行化。都解决,单事务。
1)platformtransactionmanager
平台事务管理器,spring要管理事务,必须使用事务管理器进行事务配置时,必须配置事务管理器。
2)transactiondefinition
事务详情(事务定义、事务属性),spring用于确定事务具体详情,
例如:隔离级别、是否只读、超时时间 等
进行事务配置时,必须配置详情。spring将配置项封装到该对象实例。
3)transactionstatus
事务状态,spring用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。
spring底层根据状态进行相应操作。
propagation_required , required , 必须 【默认值】 支持当前事务,a如果有事务,b将使用该事务。 如果a没有事务,b将创建一个新的事务。 propagation_supports ,supports ,支持 支持当前事务,a如果有事务,b将使用该事务。 如果a没有事务,b将以非事务执行。 propagation_mandatory,mandatory ,强制 支持当前事务,a如果有事务,b将使用该事务。 如果a没有事务,b将抛异常。 propagation_requires_new , requires_new ,必须新的 如果a有事务,将a的事务挂起,b创建一个新的事务 如果a没有事务,b创建一个新的事务 propagation_not_supported ,not_supported ,不支持 如果a有事务,将a的事务挂起,b将以非事务执行 如果a没有事务,b将以非事务执行 propagation_never ,never,从不 如果a有事务,b将抛异常 如果a没有事务,b将以非事务执行 propagation_nested ,nested ,嵌套 a和b底层采用保存点机制,形成嵌套事务。 掌握:propagation_required、propagation_requires_new、propagation_nested
基于转账的案例演示,基于druid连接池配置。druid连接池在文章。
springboot2.0 基础案例(07):集成druid连接池,配置监控界面
create table account( id int primary key auto_increment, username varchar(50), money int )engine=innodb default charset=utf8; insert into account(username,money) values('jack','10000'); insert into account(username,money) values('rose','10000'); select * from account;
该配置用于测试事务的手动管理。
/** * 事物管理器 */ @bean(name = "transactionmanager") public platformtransactionmanager transactionmanager (druiddatasource datasource){ logger.info("【transactionmanager 初始化...】"); datasourcetransactionmanager transactionmanager = new datasourcetransactionmanager(); transactionmanager.setdatasource(datasource); return transactionmanager; } /** * 创建事物手动管理模板 */ @bean(name = "transactiontemplate") public transactiontemplate transactiontemplate(platformtransactionmanager transactionmanager) logger.info("【transactiontemplate 初始化...】"); transactiontemplate transactiontemplate = new transactiontemplate() ; transactiontemplate.settransactionmanager(transactionmanager); return transactiontemplate; }
接口方法
public interface accountservice { /** * 汇款 */ void out (string outer , integer money); /** * 收款 */ void in (string inner , integer money); }
接口实现
@service public class accountserviceimpl implements accountservice { @resource private jdbctemplate jdbctemplate ; public void out(string outer, integer money) { string sql = "update account set money = money - ? where username = ?"; jdbctemplate.update(sql, money,outer); } public void in(string inner, integer money) { string sql = "update account set money = money + ? where username = ?"; jdbctemplate.update(sql, money,inner); } }
测试接口
public interface tradeservice { /** * 转账交易:没有事务管理 */ void trade1(string outer ,string inner ,integer money); /** * 转账交易:手动管理事务 */ void trade2(string outer ,string inner ,integer money); /** * 转账交易:注解管理事务 */ void trade3(string outer ,string inner ,integer money); }
接口实现
@service public class tradeserviceimpl implements tradeservice { @resource private accountservice accountservice ; @resource private transactiontemplate transactiontemplate ; @override public void trade1(string outer, string inner, integer money) { accountservice.out(outer, money); // 抛出异常 int i = 1/0; accountservice.in(inner, money); } @override public void trade2(string outer, string inner, integer money) { transactiontemplate.execute(new transactioncallbackwithoutresult() { public void dointransactionwithoutresult(transactionstatus arg0) { accountservice.out(outer, money); // 抛出异常 int i = 1/0; accountservice.in(inner, money); } }); } @transactional(value="transactionmanager",propagation= propagation.required) @override public void trade3(string outer, string inner, integer money) { accountservice.out(outer, money); // 抛出异常 int i = 1/0; accountservice.in(inner, money); } }
@runwith(springjunit4classrunner.class) @springboottest(classes = transactionapplication.class) public class tradetest { @resource private tradeservice tradeservice ; /** * 没有事务管理 * jack 减少了1000块钱,但是rose得到1000块钱 * 1 jack 9000 * 2 rose 10000 */ @test public void testtrade1 (){ tradeservice.trade1("jack", "rose", 1000); } /** * 手动管理事务 * 1 jack 10000 * 2 rose 10000 */ @test public void testtrade2 (){ tradeservice.trade2("jack", "rose", 1000); } /** * 注解管理事务 * 1 jack 10000 * 2 rose 10000 */ @test public void testtrade3 (){ tradeservice.trade3("jack", "rose", 1000); } }
github地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 码云地址:知了一笑 https://gitee.com/cicadasmile/spring-boot-base
如对本文有疑问, 点击进行留言回复!!
集合框架——Map、泛型以及Collection算法常用方法
Elasticsearch 升级 7.x 版本后,我感觉掉坑里了
Mybatis的插件运行原理以及如何编写一个Mybatis的插件
网友评论