it项目网站开发的需求文档,图书馆网站建设的要求,温州网站制作建设,长春网站优化页面【Spring Boot系列】- Spring Boot事务应用详解
一、事务简介
事务#xff08;Transaction#xff09;是数据库操作最基本单元#xff0c;逻辑上一组操作#xff0c;要么都成功。如果有一个操作失败。则事务操作都失败#xff08;回滚#xff08;Rollback#xff09;Transaction是数据库操作最基本单元逻辑上一组操作要么都成功。如果有一个操作失败。则事务操作都失败回滚Rollback。
事务的四个特性ACID:
1. 原子性Atomicity
一个事务Transaction中的所有操作要么全部完成要么全部不完成不会结束在中间某个环节。
2. 一致性Consistency
事务开始之前和事务结束以后数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则。
3. 隔离性Isolation
一个事务的执行不能被其它事务干扰即一个事务内部的操作及使用的数据对并发的其它事务是隔离的并发执行的各个事务之间不能互相打扰。
4. 隔离性Durability
事务处理结束后对数据的修改就是永久的即便系统故障也不会丢失。 其中事务隔离又分为以下 4 种不同的级别
未提交读Read uncommitted最低的隔离级别允许“脏读”dirty reads事务可以看到其他事务“尚未提交”的修改。如果另一个事务回滚那么当前事务读到的数据就是脏数据。提交读read committed一个事务可能会遇到不可重复读Non Repeatable Read的问题。不可重复读是指在一个事务内多次读同一数据在这个事务还没有结束时如果另一个事务恰好修改了这个数据那么在第一个事务中两次读取的数据就可能不一致。可重复读repeatable read: 一个事务可能会遇到幻读Phantom Read的问题。幻读是指在一个事务中第一次查询某条记录发现没有但是当试图更新这条不存在的记录时竟然能成功并且再次读取同一条记录它就神奇地出现了串行化Serializable: 最严格的隔离级别所有事务按照次序依次执行因此脏读、不可重复读、幻读都不会出现。虽然 Serializable 隔离级别下的事务具有最高的安全性但是由于事务是串行执行所以效率会大大下降应用程序的性能会急剧降低。如果没有特别重要的情景一般都不会使用 Serializable 隔离级别。
需要格外注意的是事务能否生效取决于数据库引擎是否支持事务。如MySQL的InnoDB引擎是支持事务的但是MyISAM就不支持事务。
二、Spring事务
Spring对事务提供了很好的支持。Spring借助IOC容器强大的配置能力为事务提供丰富功能支持。
Spring支持以下2种事务管理方式
声明式事务管理Spring 声明式事务管理在底层采用了 AOP 技术其最大的优点在于无须通过编程的方式管理事务只需要在配置文件中进行相关的规则声明就可以将事务规则应用到业务逻辑中。编程式事务管理编程式事务管理是通过编写代码实现的事务管理。 这种方式能够在代码中精确地定义事务的边界我们可以根据需求规定事务从哪里开始到哪里结束。
选择编程式事务还是声明式事务很大程度上就是在控制权上颗粒度和易用性之间进行权衡。
编程式对事物控制的细粒度更高我们能够精确的控制事务的边界事务的开始和结束完全取决于我们的需求但这种方式存在一个致命的缺点那就是事务规则与业务代码耦合度高难以维护因此我们很少使用这种方式对事务进行管理。声明式事务易用性更高对业务代码没有侵入性耦合度低易于维护因此这种方式也是我们最常用的事务管理方式。
三、Spring声明式事务
Spring的声明式事务管理在底层是建立在AOP的基础上的其本质是对方法前后进行拦截然后在目标方法开始之前创建或者加入一个事务在执行完目标方法之后根据执行情况提交或者回滚事务。
声明式事务最大的优点就是不需要通过编程的方式管理事务这样就不需要在业务逻辑代码中掺杂事务管理的代码只需在配置文件中做相关的事务规则声明或通过等价的基于标注的方式便可以将事务规则应用到业务逻辑中。因为事务管理本身就是一个典型的横切逻辑正是 AOP 的用武之地。Spring 开发团队也意识到了这一点为声明式事务提供了简单而强大的支持。
在开发中使用声明式事务不仅因为其简单更主要是因为这样使得纯业务代码不被污染极大方便后期的代码维护。
3.1 声明式事务的2种实现方式
配置文件的方式 即在spring xml文件中进行统一配置开发者基本上就不用关注事务的事情了代码中无需关心任何和事务相关的代码一切交给spring处理。注解的方式 只需在需要spring来帮忙管理事务的方法上加上Transaction注解就可以了注解的方式相对来说更简洁一些都需要开发者自己去进行配置可能有些同学对spring不是太熟悉所以配置这个有一定的风险做好代码review就可以了。
3.2 声明式事务注解方式5个步骤
1. 启用Spring的注释驱动事务管理功能
在spring配置类上加上EnableTransactionManagement注解
EnableTransactionManagement
public class MainConfig4 {
}当spring容器启动的时候发现有EnableTransactionManagement注解此时会拦截所有bean的创建扫描看一下bean上是否有Transaction注解类、或者父类、或者接口、或者方法中有这个注解都可以如果有这个注解spring会通过aop的方式给bean生成代理对象代理对象中会增加一个拦截器拦截器会拦截bean中public方法执行会在方法执行之前启动事务方法执行完毕之后提交或者回滚事务。
EnableTransactionManagement 的源码
Target(ElementType.TYPE)
Retention(RetentionPolicy.RUNTIME)
Documented
Import(TransactionManagementConfigurationSelector.class)
public interface EnableTransactionManagement {/*** spring是通过aop的方式对bean创建代理对象来实现事务管理的* 创建代理对象有2种方式jdk动态代理和cglib代理* proxyTargetClass为true的时候就是强制使用cglib来创建代理*/boolean proxyTargetClass() default false;/*** 用来指定事务拦截器的顺序* 我们知道一个方法上可以添加很多拦截器拦截器是可以指定顺序的* 比如你可以自定义一些拦截器放在事务拦截器之前或者之后执行就可以通过order来控制*/int order() default Ordered.LOWEST_PRECEDENCE;
}2. 定义事务管理器
事务交给spring管理那么你肯定要创建一个或者多个事务管理者有这些管理者来管理具体的事务比如启动事务、提交事务、回滚事务这些都是管理者来负责的。
spring中使用PlatformTransactionManager这个接口来表示事务管理者。
PlatformTransactionManager多个实现类用来应对不同的环境
JpaTransactionManager 如果你用jpa来操作db那么需要用这个管理器来帮你控制事务。
DataSourceTransactionManager 如果你用是指定数据源的方式比如操作数据库用的是JdbcTemplate、mybatis、ibatis那么需要用这个管理器来帮你控制事务。
HibernateTransactionManager 如果你用hibernate来操作db那么需要用这个管理器来帮你控制事务。
JtaTransactionManager 如果你用的是java中的jta来操作db这种通常是分布式事务此时需要用这种管理器来控制事务。
3. 需使用事务的目标上加Transaction注解
Transaction放在接口上那么接口的实现类中所有public都被spring自动加上事务。Transaction放在类上那么当前类以及其下无限级子类中所有pubilc方法将被spring自动加上事务。Transaction放在public方法上那么该方法将被spring自动加上事务。
Transaction参数介绍
参数描述value指定事务管理器的bean名称如果容器中有多事务管理器PlatformTransactionManager那么你得告诉spring当前配置需要使用哪个事务管理器transactionManager同valuevalue和transactionManager选配一个就行也可以为空如果为空默认会从容器中按照类型查找一个事务管理器beanpropagation事务的传播属性下篇文章详细介绍isolation事务的隔离级别就是制定数据库的隔离级别数据库隔离级别大家知道么不知道的可以去补一下timeout事务执行的超时时间秒执行一个方法比如有问题那我不可能等你一天吧可能最多我只能等你10秒 10秒后还没有执行完毕就弹出一个超时异常吧readOnly是否是只读事务比如某个方法中只有查询操作我们可以指定事务是只读的 设置了这个参数可能数据库会做一些性能优化提升查询速度rollbackFor定义零(0)个或更多异常类这些异常类必须是Throwable的子类当方法抛出这些异常及其子类异常的时候spring会让事务回滚 如果不配做那么默认会在 RuntimeException 或者 Error 情况下事务才会回滚rollbackForClassName同 rollbackFor只是这个地方使用的是类名noRollbackFor定义零(0)个或更多异常类这些异常类必须是Throwable的子类当方法抛出这些异常的时候事务不会回滚noRollbackForClassName同 noRollbackFor只是这个地方使用的是类名
4. 执行db业务操作
在Transaction标注类或者目标方法上执行业务操作此时这些方法会自动被spring进行事务管理。
Component
public class UserService {Autowiredprivate JdbcTemplate jdbcTemplate;Transactionalpublic void insertBatch(String names) {jdbcTemplate.update(truncate table t_user);for (String name : names) {jdbcTemplate.update(INSERT INTO t_user(name) VALUES (?), name);}}
}5. 启动spring容器使用bean执行业务操作
Test
public void test1() {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext();context.register(MainConfig4.class);context.refresh();UserService userService context.getBean(UserService.class);userService.insertBatch(java高并发系列, mysql系列, maven系列, mybatis系列);
}四、Spring编程式事务
通过硬编码的方式使用spring中提供的事务相关的类来控制事务。
编程式事务主要的两种用法
通过PlatformTransactionManager控制事务。通过TransactionTemplate控制事务。
4.1 PlatfornTransactionManager
这种是最原始的方式代码量较大后面其他方式都是针对这种方式的封装
Testpublic void test1() throws Exception {//定义一个数据源DataSource dataSource new DataSource();dataSource.setDriverClassName(com.mysql.jdbc.Driver);dataSource.setUrl(jdbc:mysql://localhost:3306/int?characterEncodingUTF-8serverTimezoneUTC);dataSource.setUsername(root);dataSource.setPassword(123456);dataSource.setInitialSize(5);//定义一个JdbcTemplate用来方便执行数据库增删改查JdbcTemplate jdbcTemplate new JdbcTemplate(dataSource);//1.定义事务管理器给其指定一个数据源可以把事务管理器想象为一个人这个人来负责事务的控制操作PlatformTransactionManager platformTransactionManager new DataSourceTransactionManager(dataSource);//2.定义事务属性TransactionDefinition// TransactionDefinition可以用来配置事务的属性信息比如事务隔离级别、事务超时时间、事务传播方式、是否是只读事务等等。TransactionDefinition transactionDefinition new DefaultTransactionDefinition();//3.开启事务调用platformTransactionManager.getTransaction开启事务操作得到事务状态(TransactionStatus)对象TransactionStatus transactionStatus platformTransactionManager.getTransaction(transactionDefinition);//4.执行业务操作下面就执行2个插入操作try {System.out.println(before: jdbcTemplate.queryForList(SELECT * from t_user));jdbcTemplate.update(insert into t_user (name) values (?), test1-1);jdbcTemplate.update(insert into t_user (name) values (?), test1-2);//5.提交事务platformTransactionManager.commitplatformTransactionManager.commit(transactionStatus);} catch (Exception e) {//6.回滚事务platformTransactionManager.rollbackplatformTransactionManager.rollback(transactionStatus);}System.out.println(after: jdbcTemplate.queryForList(SELECT * from t_user));}4.2 代码分析
步骤一定义事务管理器PlatformTransactionManager
事务管理器相当于一个管理员这个管理员就是用来帮你控制事务的比如开启事务提交事务回滚事务等等。
spring中使用PlatformTransactionManager这个接口来表示事务管理器
public interface PlatformTransactionManager {//获取一个事务开启事务TransactionStatus getTransaction(Nullable TransactionDefinition definition)throws TransactionException;//提交事务void commit(TransactionStatus status) throws TransactionException;//回滚事务void rollback(TransactionStatus status) throws TransactionException;
}步骤二定义事务属性TransactionDefinition
定义事务属性比如事务隔离级别、事务超时时间、事务传播方式、是否是只读事务等等。 spring中使用TransactionDefinition接口来表示事务的定义信息有个子类比较常用DefaultTransactionDefinition。
步骤三开启事务
调用事务管理器的getTransaction方法即可以开启一个事务。这个方法会返回一个TransactionStatus表示事务状态的一个对象通过TransactionStatus提供的一些方法可以用来控制事务的一些状态比如事务最终是需要回滚还是需要提交。
步骤四执行业务操作
事务管理器开启事务的时候会创建一个连接将datasource和connection映射之后丢在了ThreadLocal中而JdbcTemplate内部执行db操作的时候也需要获取连接JdbcTemplate会以自己内部的datasource去上面的threadlocal中找有没有关联的连接如果有直接拿来用若没找到将重新创建一个连接而此时是可以找到的那么JdbcTemplate就参与到spring的事务中了。
4.2 TransactionTemplate
Testpublic void test2() throws Exception {//定义一个数据源DataSource dataSource new DataSource();dataSource.setDriverClassName(com.mysql.jdbc.Driver);dataSource.setUrl(jdbc:mysql://localhost:3306/int?characterEncodingUTF-8serverTimezoneUTC);dataSource.setUsername(root);dataSource.setPassword(123456);dataSource.setInitialSize(5);//定义一个JdbcTemplate用来方便执行数据库增删改查JdbcTemplate jdbcTemplate new JdbcTemplate(dataSource);//1.定义事务管理器给其指定一个数据源可以把事务管理器想象为一个人这个人来负责事务的控制操作PlatformTransactionManager platformTransactionManager new DataSourceTransactionManager(dataSource);//2.定义事务属性TransactionDefinitionTransactionDefinition可以用来配置事务的属性信息比如事务隔离级别、事务超时时间、事务传播方式、是否是只读事务等等。DefaultTransactionDefinition transactionDefinition new DefaultTransactionDefinition();transactionDefinition.setTimeout(10);//3.创建TransactionTemplate对象TransactionTemplate transactionTemplate new TransactionTemplate(platformTransactionManager,transactionDefinition);/*** 4.通过TransactionTemplate提供的方法执行业务操作* 主要有2个方法* 1.executeWithoutResult(ConsumerTransactionStatus action)没有返回值的需传递一个Consumer对象在accept方法中做业务操作* 2.T T execute(TransactionCallbackT action)有返回值的需要传递一个TransactionCallback对象在doInTransaction方法中做业务操作* 调用execute方法或者executeWithoutResult方法执行完毕之后事务管理器会自动提交事务或者回滚事务。* 那么什么时候事务会回滚有2种方式* 1transactionStatus.setRollbackOnly();将事务状态标注为回滚状态* 2execute方法或者executeWithoutResult方法内部抛出异常* 什么时候事务会提交* 方法没有异常 未调用过transactionStatus.setRollbackOnly();*/transactionTemplate.executeWithoutResult(new ConsumerTransactionStatus() {Overridepublic void accept(TransactionStatus transactionStatus) {jdbcTemplate.update(insert into t_user (name) values (?), transactionTemplate-1);jdbcTemplate.update(insert into t_user (name) values (?), transactionTemplate-2);}});System.out.println(after: jdbcTemplate.queryForList(SELECT * from t_user));} 文章转载自: http://www.morning.bssjz.cn.gov.cn.bssjz.cn http://www.morning.knryp.cn.gov.cn.knryp.cn http://www.morning.tnwwl.cn.gov.cn.tnwwl.cn http://www.morning.ylqpp.cn.gov.cn.ylqpp.cn http://www.morning.sxmbk.cn.gov.cn.sxmbk.cn http://www.morning.mjgxl.cn.gov.cn.mjgxl.cn http://www.morning.rntgy.cn.gov.cn.rntgy.cn http://www.morning.dmthy.cn.gov.cn.dmthy.cn http://www.morning.gbnsq.cn.gov.cn.gbnsq.cn http://www.morning.qxjck.cn.gov.cn.qxjck.cn http://www.morning.rxfgh.cn.gov.cn.rxfgh.cn http://www.morning.nflpk.cn.gov.cn.nflpk.cn http://www.morning.rqmqr.cn.gov.cn.rqmqr.cn http://www.morning.xrwbc.cn.gov.cn.xrwbc.cn http://www.morning.rmmz.cn.gov.cn.rmmz.cn http://www.morning.djbhz.cn.gov.cn.djbhz.cn http://www.morning.tnmmp.cn.gov.cn.tnmmp.cn http://www.morning.lsxabc.com.gov.cn.lsxabc.com http://www.morning.jklns.cn.gov.cn.jklns.cn http://www.morning.kjnfs.cn.gov.cn.kjnfs.cn http://www.morning.lmfmd.cn.gov.cn.lmfmd.cn http://www.morning.wklmj.cn.gov.cn.wklmj.cn http://www.morning.rqkzh.cn.gov.cn.rqkzh.cn http://www.morning.pwdgy.cn.gov.cn.pwdgy.cn http://www.morning.qfdyt.cn.gov.cn.qfdyt.cn http://www.morning.dmjhp.cn.gov.cn.dmjhp.cn http://www.morning.pcgrq.cn.gov.cn.pcgrq.cn http://www.morning.rbkdg.cn.gov.cn.rbkdg.cn http://www.morning.hqrr.cn.gov.cn.hqrr.cn http://www.morning.kstgt.cn.gov.cn.kstgt.cn http://www.morning.stfdh.cn.gov.cn.stfdh.cn http://www.morning.jzmqk.cn.gov.cn.jzmqk.cn http://www.morning.gfrtg.com.gov.cn.gfrtg.com http://www.morning.wmfmj.cn.gov.cn.wmfmj.cn http://www.morning.amlutsp.cn.gov.cn.amlutsp.cn http://www.morning.addai.cn.gov.cn.addai.cn http://www.morning.rrqbm.cn.gov.cn.rrqbm.cn http://www.morning.xxiobql.cn.gov.cn.xxiobql.cn http://www.morning.nyjgm.cn.gov.cn.nyjgm.cn http://www.morning.qmnjn.cn.gov.cn.qmnjn.cn http://www.morning.prsxj.cn.gov.cn.prsxj.cn http://www.morning.lsnnc.cn.gov.cn.lsnnc.cn http://www.morning.thlr.cn.gov.cn.thlr.cn http://www.morning.jxzfg.cn.gov.cn.jxzfg.cn http://www.morning.xsgxp.cn.gov.cn.xsgxp.cn http://www.morning.tytly.cn.gov.cn.tytly.cn http://www.morning.kfmlf.cn.gov.cn.kfmlf.cn http://www.morning.gypcr.cn.gov.cn.gypcr.cn http://www.morning.slqgl.cn.gov.cn.slqgl.cn http://www.morning.gpmrj.cn.gov.cn.gpmrj.cn http://www.morning.qwlml.cn.gov.cn.qwlml.cn http://www.morning.nwllb.cn.gov.cn.nwllb.cn http://www.morning.qzglh.cn.gov.cn.qzglh.cn http://www.morning.mhlsx.cn.gov.cn.mhlsx.cn http://www.morning.nrxsl.cn.gov.cn.nrxsl.cn http://www.morning.jcbmm.cn.gov.cn.jcbmm.cn http://www.morning.rlbc.cn.gov.cn.rlbc.cn http://www.morning.przc.cn.gov.cn.przc.cn http://www.morning.yjfzk.cn.gov.cn.yjfzk.cn http://www.morning.cjwkf.cn.gov.cn.cjwkf.cn http://www.morning.nbfkk.cn.gov.cn.nbfkk.cn http://www.morning.ckfqt.cn.gov.cn.ckfqt.cn http://www.morning.lywys.cn.gov.cn.lywys.cn http://www.morning.jfnbh.cn.gov.cn.jfnbh.cn http://www.morning.gagapp.cn.gov.cn.gagapp.cn http://www.morning.ghrhb.cn.gov.cn.ghrhb.cn http://www.morning.tqldj.cn.gov.cn.tqldj.cn http://www.morning.nwczt.cn.gov.cn.nwczt.cn http://www.morning.rrxgx.cn.gov.cn.rrxgx.cn http://www.morning.kzxlc.cn.gov.cn.kzxlc.cn http://www.morning.mrtdq.cn.gov.cn.mrtdq.cn http://www.morning.jpwmk.cn.gov.cn.jpwmk.cn http://www.morning.dskmq.cn.gov.cn.dskmq.cn http://www.morning.fqnql.cn.gov.cn.fqnql.cn http://www.morning.pqchr.cn.gov.cn.pqchr.cn http://www.morning.lmxrt.cn.gov.cn.lmxrt.cn http://www.morning.hlnys.cn.gov.cn.hlnys.cn http://www.morning.bpwdc.cn.gov.cn.bpwdc.cn http://www.morning.nnykz.cn.gov.cn.nnykz.cn http://www.morning.nfpgc.cn.gov.cn.nfpgc.cn