保险公司网站查询,怎样自创网站,网站开发的实施方案,电子商务网站建设薛万欣目录 1.编程式事务#xff08;手动编写代码#xff09;2.声明式事务#xff08;利用注解#xff09;2.1 Transactional作用范围2.2 Transactional参数说明2.3 Transactional工作原理 3.Spring 中设置事务隔离级别3.1 事务四大特性ACID3.2 事务的隔离级别3.2 Spring中设置事… 目录 1.编程式事务手动编写代码2.声明式事务利用注解2.1 Transactional作用范围2.2 Transactional参数说明2.3 Transactional工作原理 3.Spring 中设置事务隔离级别3.1 事务四大特性ACID3.2 事务的隔离级别3.2 Spring中设置事务的隔离级别 4.Spring 中事务传播机制4.1 事务的传播机制是什么4.2 传播机制和隔离级别的作用4.3事务传播机制的种类 5.Spring 中事务传播机制的使用5.1 支持当前事务REQUIRED5.2 不支持当前事务REQUIRES_NEW5.3 不支持当前事务NEVER抛异常5.4 NESTED嵌套事务5.5 嵌套事务和加入事务的区别 事务定义将一组操作封装成⼀个执⾏单元封装到⼀起要么全部成功要么全部失败 Spring 中的事务操作分为两类
编程式事务⼿动写代码操作事务。声明式事务利⽤注解⾃动开启和提交事务。 1.编程式事务手动编写代码
编程式事务有三个步骤:
开启事务获取事务。提交事务。回滚事务。
SpringBoot 内置了两个对象:
DataSourceTransactionManager ⽤来获取事务开启事务、提交或回滚事务 TransactionDefinition 是事务的属性在获取事务的时候需要将TransactionDefinition 传递进去从⽽获得⼀个事务 TransactionStatus
实现代码如下
package com.example.mybatisdemo.controller;import com.example.mybatisdemo.model.User;
import com.example.mybatisdemo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** 手动提交事务*/
Slf4j
RequestMapping(/trans)
RestController
public class TransactionController {Autowiredprivate UserService userService;//获取数据库事务管理器Autowiredprivate DataSourceTransactionManager dataSourceTransactionManager;//数据库事务默认配置Autowiredprivate TransactionDefinition transactionDefinition;RequestMapping(/addUser)public Integer addUser(String username,String password){//获取一个事务TransactionStatus transaction dataSourceTransactionManager.getTransaction(transactionDefinition);User usernew User(username,password);Integer result userService.insert(user);log.info(影响行数result);//回滚到transaction状态//dataSourceTransactionManager.rollback(transaction);//事务提交dataSourceTransactionManager.commit(transaction);return result;}
} 2.声明式事务利用注解
声明式事务的实现很简单只需要在需要的⽅法上添加 Transactional 注解就可以实现了⽆需⼿动开启事务和提交事务进⼊⽅法时⾃动开启事务⽅法执⾏完会⾃动提交事务如果中途发⽣了没有处理的异常会⾃动回滚事务具体实现代码如下
/*** 使用注解提交事务*/
Slf4j
RequestMapping(/trans2)
RestController
public class TransactionController2 {Autowiredprivate UserService userService;Transactional //事务注解//在遇到运行时异常(RuntimeException)和error才会回滚非运行时异常不回滚RequestMapping(/addUser)public Integer addUser(String username,String password){User usernew User(username,password);Integer result userService.insert(user);log.info(影响行数result);//发生异常时事务会回滚//int a10/0;return result;}
}补充如果异常被捕获了事务不会回滚代码示例 TransactionalRequestMapping(/addUser3)public Integer addUser3(String username,String password) throws Exception {User usernew User(username,password);Integer result userService.insert(user);log.info(影响行数result);try {int a10/0;} catch (Exception e){e.printStackTrace();}return result;}2.1 Transactional作用范围
Transactional 可以⽤来修饰⽅法或类 修饰⽅法时需要注意只能应⽤到 public ⽅法上否则不⽣效。推荐此种⽤法。 修饰类时表明该注解对该类中所有的 public ⽅法都⽣效
2.2 Transactional参数说明 rollbackFor和noRollbackFor示例代码 /*** 指定异常不回滚* param username* param password* return*/Transactional(noRollbackFor ArithmeticException.class)RequestMapping(/addUser)public Integer addUser1(String username,String password){User usernew User(username,password);Integer result userService.insert(user);log.info(影响行数result);//发生异常时事务会回滚//int a10/0;return result;}/*** 指定异常回滚* param username* param password* return*/Transactional(rollbackFor Exception.class) //所有异常都回滚RequestMapping(/addUser2)public Integer addUser2(String username,String password) throws Exception {User usernew User(username,password);Integer result userService.insert(user);log.info(影响行数result);throwException();return result;}public void throwException() throws Exception{throw new IOException();}
2.3 Transactional工作原理
Transactional 是基于 AOP 实现的AOP ⼜是使⽤动态代理实现的。如果⽬标对象实现了接⼝默认情况下会采⽤ JDK 的动态代理如果⽬标对象没有实现了接⼝,会使⽤ CGLIB 动态代理。 Transactional 在开始执⾏业务之前通过代理先开启事务在执⾏成功之后再提交事务。如果中途遇到的异常则回滚事务。 Transactional 实现思路预览 3.Spring 中设置事务隔离级别
3.1 事务四大特性ACID
事务有4 ⼤特性ACID原⼦性、持久性、⼀致性和隔离性具体概念如下
原⼦性Atomicity或称不可分割性⼀个事务transaction中的所有操作要么全部完成要么全部不完成不会结束在中间某个环节。事务在执⾏过程中发⽣错误会被回滚Rollback到事务开始前的状态就像这个事务从来没有执⾏过⼀样。
⼀致性Consistency在事务开始之前和事务结束以后数据库的完整性没有被破坏。这表示写⼊的资料必须完全符合所有的预设规则这包含资料的精确度、串联性以及后续数据库可以⾃发性地完成预定的⼯作。
持久性Durability事务处理结束后对数据的修改就是永久的即便系统故障也不会丢失。
隔离性Isolation⼜称独⽴性数据库允许多个并发事务同时对其数据进⾏读写和修改的能⼒隔离性可以防⽌多个事务并发执⾏时由于交叉执⾏⽽导致数据的不⼀致。事务隔离分为不同级别包括读未提交Readuncommitted、读提交read committed、可重复读repeatable read和串⾏化Serializable。
3.2 事务的隔离级别
事务的隔离级别有四种
READ UNCOMMITTED读未提交也叫未提交读该隔离级别的事务可以看到其他事务中未提交的数据。该隔离级别因为可以读取到其他事务中未提交的数据⽽未提交的数据可能会发⽣回滚因此我们把该级别读取到的数据称之为脏数据把这个问题称之为脏读。READ COMMITTED读已提交也叫提交读该隔离级别的事务能读取到已经提交事务的数据因此它不会有脏读问题。但由于在事务的执⾏中可以读取到其他事务提交的结果所以在不同时间的相同 SQL 查询中可能会得到不同的结果这种现象叫做不可重复读。Oracle默认隔离级别REPEATABLE READ可重复读是 MySQL 的默认事务隔离级别它能确保同⼀事务多次查询的结果⼀致。但也会有新的问题⽐如此级别的事务正在执⾏时另⼀个事务成功的插⼊某条数据但因为它每次查询的结果都是⼀样的所以会导致查询不到这条数据⾃⼰重复插⼊时⼜失败因为唯⼀约束的原因。明明在事务中查询不到这条信息但⾃⼰就是插⼊不进去这就叫幻读Phantom Read。MySQL默认隔离级别SERIALIZABLE序列化事务最⾼隔离级别它会强制事务排序使之不会发⽣冲突从⽽解决了脏读、不可重复读和幻读问题但因为执⾏效率低所以真正使⽤的场景并不多。 ● 脏读⼀个事务读取到了另⼀个事务修改的数据之后后⼀个事务⼜进⾏了回滚操作从⽽导致第⼀个事务读取的数据是错误的。 ● 不可重复读⼀个事务两次查询得到的结果不同因为在两次查询中间有另⼀个事务把数据修改了。 ● 幻读⼀个事务两次查询中得到的结果集不同因为在两次查询中另⼀个事务有新增了⼀部分数据。
3.2 Spring中设置事务的隔离级别
Spring 中事务隔离级别包含以下 5 种
Isolation.DEFAULT以连接的数据库的事务隔离级别为主。Isolation.READ_UNCOMMITTED读未提交可以读取到未提交的事务存在脏读。Isolation.READ_COMMITTED读已提交只能读取到已经提交的事务解决了脏读存在不可重复读。Isolation.REPEATABLE_READ可重复读解决了不可重复读但存在幻读MySQL默认级别。Isolation.SERIALIZABLE串⾏化可以解决所有并发问题但性能太低。
从上述介绍可以看出相⽐于 MySQL 的事务隔离级别Spring 的事务隔离级别只是多了⼀个 Isolation.DEFAULT以数据库的全局事务隔离级别为主
Spring 中事务隔离级别只需要设置 Transactional ⾥的 isolation 属性即可具体实现代码如下
RequestMapping(/save)
Transactional(isolation Isolation.SERIALIZABLE)
public Object save(User user) {// 业务实现
}4.Spring 中事务传播机制
4.1 事务的传播机制是什么
先来看一个示例 此时有3个事务A调用了B和C如果C事务执行失败B事务执行成功那么B最终能否成功A能否成功
答案是在不同的事务传播机制中结果是不同的。
Spring 事务传播机制定义了多个包含了事务的⽅法相互调⽤时事务是如何在这些⽅法间进⾏传递的。
4.2 传播机制和隔离级别的作用
事务隔离级别是保证多个并发事务执⾏的可控性的稳定性的⽽事务传播机制是保证⼀个事务在多个调⽤⽅法间的可控性的稳定性的。 举个例⼦像新冠病毒⼀样它有不同的隔离⽅式酒店隔离还是居家隔离是为了保证疫情可控然⽽在每个⼈的隔离过程中会有很多个执⾏的环节⽐如酒店隔离需要负责⼈员运送、物品运送、消杀原⽣活区域、定时核算检查和定时送餐等很多环节⽽事务传播机制就是保证⼀个事务在传递过程中是可靠性的回到本身案例中就是保证每个⼈在隔离的过程中可控的。 事务隔离级别解决的是多个事务同时调⽤⼀个数据库的问题如下图所示 ⽽事务传播机制解决的是⼀个事务在多个节点⽅法中传递的问题如下图所示
4.3事务传播机制的种类
Spring 事务传播机制包含以下 7 种
Propagation.REQUIRED默认的事务传播级别它表示如果当前存在事务则加⼊该事务如果当前没有事务则创建⼀个新的事务。Propagation.SUPPORTS如果当前存在事务则加⼊该事务如果当前没有事务则以⾮事务的⽅式继续运⾏。Propagation.MANDATORYmandatory强制性如果当前存在事务则加⼊该事务如果当前没有事务则抛出异常。Propagation.REQUIRES_NEW表示创建⼀个新的事务如果当前存在事务则把当前事务挂起。也就是说不管外部⽅法是否开启事务Propagation.REQUIRES_NEW 修饰的内部⽅法会新开启⾃⼰的事务且开启的事务相互独⽴互不⼲扰。Propagation.NOT_SUPPORTED以⾮事务⽅式运⾏如果当前存在事务则把当前事务挂起。Propagation.NEVER以⾮事务⽅式运⾏如果当前存在事务则抛出异常。Propagation.NESTED如果当前存在事务则创建⼀个事务作为当前事务的嵌套事务来运⾏如果当前没有事务则该取值等价于 PROPAGATION_REQUIRED
以上 7 种传播⾏为可以根据是否⽀持当前事务分为以下 3类 5.Spring 中事务传播机制的使用
5.1 支持当前事务REQUIRED
正常情况演示 先开启事务插入用户再插入日志 TransactionalRequestMapping(/addUser)public boolean addUser(String username,String password){//插入用户表User usernew User(username,password);userService.insert(user);//插入日志表UserLog userLognew UserLog(username);userLogService.insertLog(userLog);return true;}UserService实现代码 Transactional(propagation Propagation.REQUIRED)public Integer insert(User user) {return userMapper.insert(user);}UserLogService实现代码 Transactional(propagation Propagation.REQUIRED)public Integer insertLog(UserLog userLog){return userLogMapper.insertLog(userLog);}执行结果数据库数据成功插入。
错误情况演示 先开启事务插入用户再插入日志插入日志异常
UserLogService实现代码出现除0异常 Transactional(propagation Propagation.REQUIRED)public Integer insertLog(UserLog userLog){Integer resultuserLogMapper.insertLog(userLog);int a10/0;return result;}执行结果程序报错数据库没有插入数据。
执行流程描述
UserService 中的保存⽅法正常执⾏完成。UserLogService 保存⽇志程序报错因为使⽤的是 Controller 中的事务所以整个事务回滚。
5.2 不支持当前事务REQUIRES_NEW
先开启事务插入用户再插入日志插入日志异常 TransactionalRequestMapping(/addUser)public boolean addUser(String username,String password){//插入用户表User usernew User(username,password);userService.insert(user);//插入日志表UserLog userLognew UserLog(username);userLogService.insertLog(userLog);return true;}UserService实现代码 Transactional(propagation Propagation.REQUIRES_NEW)public Integer insert(User user) {return userMapper.insert(user);}UserLogService实现代码 Transactional(propagation Propagation.REQUIRES_NEW)public Integer insertLog(UserLog userLog){Integer resultuserLogMapper.insertLog(userLog);int a10/0;return result;}执行结果用户表数据插入成功日志表数据插入失败 原因
5.3 不支持当前事务NEVER抛异常
先开启事务插入用户再插入日志插入日志异常
UserService实现代码 Transactional(propagation Propagation.NEVER)public Integer insert(User user) {return userMapper.insert(user);}UserLogService实现代码 Transactional(propagation Propagation.NEVER)public Integer insertLog(UserLog userLog){Integer resultuserLogMapper.insertLog(userLog);int a10/0;return result;}执行结果程序报错执行失败数据库没有插入数据。
5.4 NESTED嵌套事务
先开启事务插入用户再插入日志插入日志异常
UserService实现代码 Transactional(propagation Propagation.NESTED)public Integer insert(User user) {return userMapper.insert(user);}UserLogService实现代码 Transactional(propagation Propagation.NESTED)public Integer insertLog(UserLog userLog){Integer resultuserLogMapper.insertLog(userLog);int a10/0;return result;}执行结果执行失败数据库没有插入数据。
代码①现在修改一下UserLogService实现代码加入回滚 Transactional(propagation Propagation.NESTED)public Integer insertLog(UserLog userLog){Integer resultuserLogMapper.insertLog(userLog);try {int a 10 / 0;}catch (Exception e){//设置回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}return result;}执行结果日志表插入成功用户表插入失败 原因在UserLogService加入部分回滚用户表运行成功日志表回滚了。
代码②现在修改一下UserLogService实现代码将NESTED改为REQUIRED Transactional(propagation Propagation.REQUIRED)public Integer insertLog(UserLog userLog){Integer resultuserLogMapper.insertLog(userLog);try {int a 10 / 0;}catch (Exception e){//设置回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}return result;}执行结果数据表没有插入数据 原因日志表回滚用户表也回滚了
5.5 嵌套事务和加入事务的区别
由上面代码①和代码②可得
嵌套事务NESTED和加⼊事务REQUIRED 的区别
整个事务如果全部执⾏成功⼆者的结果是⼀样的。如果事务执⾏到⼀半失败了那么加⼊事务整个事务会全部回滚⽽嵌套事务会局部回滚不会影响上⼀个⽅法中执⾏的结果。 文章转载自: http://www.morning.mcwgn.cn.gov.cn.mcwgn.cn http://www.morning.dglszn.com.gov.cn.dglszn.com http://www.morning.gqmhq.cn.gov.cn.gqmhq.cn http://www.morning.tnkwj.cn.gov.cn.tnkwj.cn http://www.morning.stxg.cn.gov.cn.stxg.cn http://www.morning.gxtbn.cn.gov.cn.gxtbn.cn http://www.morning.lgpzq.cn.gov.cn.lgpzq.cn http://www.morning.qxgmp.cn.gov.cn.qxgmp.cn http://www.morning.zcyxq.cn.gov.cn.zcyxq.cn http://www.morning.ldzxf.cn.gov.cn.ldzxf.cn http://www.morning.ftsmg.com.gov.cn.ftsmg.com http://www.morning.bpmdh.cn.gov.cn.bpmdh.cn http://www.morning.jtmrx.cn.gov.cn.jtmrx.cn http://www.morning.tnnfy.cn.gov.cn.tnnfy.cn http://www.morning.btgxf.cn.gov.cn.btgxf.cn http://www.morning.wlxfj.cn.gov.cn.wlxfj.cn http://www.morning.klcdt.cn.gov.cn.klcdt.cn http://www.morning.zcncb.cn.gov.cn.zcncb.cn http://www.morning.mrfr.cn.gov.cn.mrfr.cn http://www.morning.pwqyd.cn.gov.cn.pwqyd.cn http://www.morning.fmrd.cn.gov.cn.fmrd.cn http://www.morning.ntzfj.cn.gov.cn.ntzfj.cn http://www.morning.gkfwp.cn.gov.cn.gkfwp.cn http://www.morning.znrgq.cn.gov.cn.znrgq.cn http://www.morning.rxkl.cn.gov.cn.rxkl.cn http://www.morning.lkbyj.cn.gov.cn.lkbyj.cn http://www.morning.mqss.cn.gov.cn.mqss.cn http://www.morning.pznhn.cn.gov.cn.pznhn.cn http://www.morning.ccpnz.cn.gov.cn.ccpnz.cn http://www.morning.hmbtb.cn.gov.cn.hmbtb.cn http://www.morning.bpmnh.cn.gov.cn.bpmnh.cn http://www.morning.c7510.cn.gov.cn.c7510.cn http://www.morning.ydxwj.cn.gov.cn.ydxwj.cn http://www.morning.daxifa.com.gov.cn.daxifa.com http://www.morning.kkzwn.cn.gov.cn.kkzwn.cn http://www.morning.qyfqx.cn.gov.cn.qyfqx.cn http://www.morning.qykxj.cn.gov.cn.qykxj.cn http://www.morning.nzklw.cn.gov.cn.nzklw.cn http://www.morning.ctswj.cn.gov.cn.ctswj.cn http://www.morning.daxifa.com.gov.cn.daxifa.com http://www.morning.rtsx.cn.gov.cn.rtsx.cn http://www.morning.wfjyn.cn.gov.cn.wfjyn.cn http://www.morning.wkgyz.cn.gov.cn.wkgyz.cn http://www.morning.fwzjs.cn.gov.cn.fwzjs.cn http://www.morning.jtsdk.cn.gov.cn.jtsdk.cn http://www.morning.ypktc.cn.gov.cn.ypktc.cn http://www.morning.cbczs.cn.gov.cn.cbczs.cn http://www.morning.dfffm.cn.gov.cn.dfffm.cn http://www.morning.kmqwp.cn.gov.cn.kmqwp.cn http://www.morning.grnhb.cn.gov.cn.grnhb.cn http://www.morning.gpnfg.cn.gov.cn.gpnfg.cn http://www.morning.snktp.cn.gov.cn.snktp.cn http://www.morning.jwfkk.cn.gov.cn.jwfkk.cn http://www.morning.hnk25076he.cn.gov.cn.hnk25076he.cn http://www.morning.fcftj.cn.gov.cn.fcftj.cn http://www.morning.wjdgx.cn.gov.cn.wjdgx.cn http://www.morning.mbbgk.com.gov.cn.mbbgk.com http://www.morning.byjwl.cn.gov.cn.byjwl.cn http://www.morning.lxyyp.cn.gov.cn.lxyyp.cn http://www.morning.qwdlj.cn.gov.cn.qwdlj.cn http://www.morning.xzkgp.cn.gov.cn.xzkgp.cn http://www.morning.rqckh.cn.gov.cn.rqckh.cn http://www.morning.vjwkb.cn.gov.cn.vjwkb.cn http://www.morning.nypsz.cn.gov.cn.nypsz.cn http://www.morning.krzrg.cn.gov.cn.krzrg.cn http://www.morning.ldsgm.cn.gov.cn.ldsgm.cn http://www.morning.wjlhp.cn.gov.cn.wjlhp.cn http://www.morning.xwbld.cn.gov.cn.xwbld.cn http://www.morning.jxgyg.cn.gov.cn.jxgyg.cn http://www.morning.qqzdr.cn.gov.cn.qqzdr.cn http://www.morning.jbtzx.cn.gov.cn.jbtzx.cn http://www.morning.sftpg.cn.gov.cn.sftpg.cn http://www.morning.ffgbq.cn.gov.cn.ffgbq.cn http://www.morning.lffrh.cn.gov.cn.lffrh.cn http://www.morning.qpqwd.cn.gov.cn.qpqwd.cn http://www.morning.rszt.cn.gov.cn.rszt.cn http://www.morning.fwlch.cn.gov.cn.fwlch.cn http://www.morning.ctqbc.cn.gov.cn.ctqbc.cn http://www.morning.btns.cn.gov.cn.btns.cn http://www.morning.jpkhn.cn.gov.cn.jpkhn.cn