SpringBoot-事务应用场景和隔离级别与传播行为
参考:https://blog.csdn.net/huangjun0210/article/details/84202333 这位大哥写得很好,后来我才看到
首先上SpringBoot事务注意事项
6.事务被捕捉了则无法回滚事务;
第3点:修改捕捉指定异常:
@Transactional(rollbackFor=Exception.class)
第5点:说白了就是同一个C类里面(含有方法A,方法B),如果方法A调用事务方法B。则事务会失效;
要改成方法A放到另一个类(D)当中,方法B放在不同的类当中才会生效;
注解@transactional的底层实现是Spring AOP技术,而Spring AOP技术使用的是动态代理。这就意味着对于静态(static)方法和非public方法,注解@Transactional是失效的。
自调用是指一个类的一个方法去调用自身另外一个方法的过程。在自调用的过程中,是类自身的调用,而不是代理对象去调用, 那么就不会产生 AOP,这样 Spring就不能把你的代码织入到约定的流程中。
为了克服这个问题,一方面可以写两个Service,用一个Service去调用另一个Service,这样就是代理对象的调用。Spring才会将你的代码织入事务流程。另一方面,也可以从Spring IoC容器中获取代理对象来启用AOP。从Spring IoC容器中获取代理对象的代码实例如下:
事务隔离级别:(mysql隔离级别自行学习)
DEFAULT
:这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是: READ_COMMITTED
。
READ_UNCOMMITTED
:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读和不可重复读;几乎不用
READ_COMMITTED
:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。 (
博主通常可能用多个地方触发某字段更新操作,以最后一个事务提交为准:
例子.用户A修改用户名先开启事务,后台管理员后修改用户A的用户名,则以后台管理员修改为准;
解释:因为在某些情况下,用户A需要执行的事务很长(时间),在这个时候管理员再去修改(比用户A先执行完提交更新事务),在用户A事务提交后,则用户A是最后修改,相当于管理员修改失败了;
这个时候如果开启了该级别,那么后台管理员所触发事务会等待用户A提交完毕,可能出现延迟、锁报错;不可避免幻读
总结;一般博主只使用在后台管理系统,因为会出现延迟、等待的问题导致报错,要是Api前台使用会比较慢;
)
REPEATABLE_READ
:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读。
(
博主通常可能用在区间统计业务(还没用过,要是有这种业务一般我在java中处理了)
例子.下午五点统计钱包流水表今天的所有数据;需要查询两次同样的数据;
解释:查出来在java中分别计算(在这个期间你可能代码写错了,导致数据错了),这个时候你需要再查一遍数据库进行统计对比
这个时候你开启了这个级别;你统计的数据与数据库不一样,那么你就可以监测到自己统计错误了;
总结;mysql默认
)
SERIALIZABLE
:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。(几乎不用)
传播行为
package org.springframework.transaction.annotation;
public enum Propagation {
REQUIRED(0),
SUPPORTS(1),
MANDATORY(2),
REQUIRES_NEW(3),
NOT_SUPPORTED(4),
NEVER(5),
NESTED(6);
private final int value;
private Propagation(int value) {
this.value = value;
}
public int value() {
return this.value;
}
}
2.1 REQUIRED(0)
需要事务,它是默认传播行为,如果当前存在事务,就沿用当前事务,否则新建一个事务运行子方法。
2.2 SUPPORTS(1)
支持事务,如果当前存在事务,就沿用当前事务,如果不存在,则继续采用无事务的方式运行子方法。
2.3 MANDATORY(2)
必须使用事务,如果当前没有事务,则会抛出异常,如果存在当前事务,就沿用当前事务。
2.4 REQUIRES_NEW(3)
无论当前事务是否存在,都会创建新事务运行方法,这样新事务就可以拥有新的锁和隔离级别等特性,与当前事务相互独立。
2.5 NOT_SUPPORTED(4)
不支持事务,当前存在事务时,将挂起事务,运行方法。
2.6 NEVER(5)
不支持事务,如果当前方法存在事务,则抛出异常,否则继续使用无事务机制运行。
2.7 NESTED(6)
在当前方法调用子方法时,如果子方法发生异常,只回滚子方法执行过的SQL,而不回滚当前方法的事务。
常用的传播行为主要有三种:REQUIRED 、REQUIRES_NEW、 NESTED。
3. @Transactional的自调用失效问题
注解@transactional的底层实现是Spring AOP技术,而Spring AOP技术使用的是动态代理。这就意味着对于静态(static)方法和非public方法,注解@Transactional是失效的。
自调用是指一个类的一个方法去调用自身另外一个方法的过程。在自调用的过程中,是类自身的调用,而不是代理对象去调用, 那么就不会产生 AOP,这样 Spring就不能把你的代码织入到约定的流程中。
为了克服这个问题,一方面可以写两个Service,用一个Service去调用另一个Service,这样就是代理对象的调用。Spring才会将你的代码织入事务流程。另一方面,也可以从Spring IoC容器中获取代理对象来启用AOP。从Spring IoC容器中获取代理对象的代码实例如下:
import com.springboot.web.dao.UserDao;
import com.springboot.web.model.User;
import com.springboot.web.service.UserService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class UserServiceImpl implements UserService, ApplicationContextAware {
@Autowired
UserDao userDao;
private ApplicationContext applicationContext;
//实现生命周期方法,设置Ioc容器
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
public void createUsers(List<User> userList){
UserService userService = applicationContext.getBean(UserService.class);
for(User user : userList){
userService.createUser(user);
}
}
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRES_NEW)
public void createUser(User user){
userDao.createUser(user);
}
}
}
SpringBoot-事务应用场景和隔离级别与传播行为相关推荐
- SpringBoot之事务处理:隔离级别与传播行为
在Spring中,数据库事务是通过AOP技术来提供服务的.对于声明式事务,是使用@Transactional进行标注的.在@Transactional允许配置许多事物的属性,如事务的隔离级别与传播行为 ...
- Java提升篇-事务隔离级别和传播机制
转载自 Java提升篇-事务隔离级别和传播机制 问题的提出 为了保证并发操作数据的正确性及一致性,SQL规范于1992年提出了数据库事务隔离级别. 事务隔离级别分类 事务隔离级别由低往高可分为以下几类 ...
- MySQL事务的4种隔离级别
文章目录 1 简介 2 什么是数据库事务? 2.1 事务的四大特性(ACID) 3 并发事务会导致的问题 3.1 本文会使用到的 SQL 语句: 3.1.1 示例表结构 3.1.2 查询事务的默认隔离 ...
- spring事务的隔离级别和传播特性详解(附实例)
spring支持编程式事务管理和声明式事务管理两种方式. 编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager.对于编程式事务 ...
- 数据库事务的ACID及隔离级别
文章目录 ACID 概念 四大特性 并发控制 隔离级别 串行化 可重复读 提交读 未提交读 默认隔离级别 读现象举例 脏读 不可重复读 幻读 隔离级别 VS 读现象 隔离级别 VS 锁持续时间 ACI ...
- Java事务的ACID属性和四种隔离级别和传播机制
事务的ACID属性 数据库管理系统中事务(transaction)的四个特性(分析时根据首字母缩写依次解释):原子性(Atomicity).一致性(Consistency).隔离性(Isolation ...
- 事务的四种隔离级别(一)Read uncommitted
背景知识 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别. 之所以提出事务隔离级别,是因为同一个应用程序中的多个事务或不同应用程序中的多个事务在同一个数据集上并发执行时, 可能会 ...
- mysql隔离级别 简书_数据库事务和四种隔离级别
什么是事务 事务(Transaction):访问并可能更新数据库中各种数据项的一个程序执行单元(unit),它通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起 ...
- oracle事务重要属性,Oracle中的事务(2)--属性和隔离级别
事务的属性 1.只读属性(read only) 只读事务,只执行查询操作,而不允许执行DML(增.删.改)操作,使用只读事务,可以让用户只取到某个时间点的数据. 假如有一个机票代售点,有一个管理员想在 ...
最新文章
- 使用估算器、tf.keras 和 tf.data 进行多 GPU 训练
- stylus-loader (copy)
- 05_数据的特征处理,归一化,标准化、缺失值处理,以及案例,使用场景,处理办法等
- 牛客网JAVA专项联系共899题--个人记录学习经历
- layui添加复选框_layui复选框使用介绍
- 金融行业文档管理系统的八大创新
- Python 命名空间
- vue如何集成阿里云视频服务组件(aliplayer)视频功能是使用el-dialog 弹出aliplayer播放
- window-批量创建文件夹
- React 优化:懒惰加载(lazy loading)
- Java蓝桥杯 算法提高 九宫格
- c语言编写生日祝福语大全,生日卡片祝福语(精选50句)
- 大数据Hadoop之——Cloudera Hadoop(CM 6.3.1+CDH 6.3.2环境部署)
- 刘天佐加盟《经济适用男》 变身木讷IT精英_0
- 什么是区块链----概念
- android小米推送,Android手机端小米推送Demo解析和实现方法
- 00后大学生在数学真理阳光下学习微积分
- 微信公众号订阅号开发的学习(二):获取用户发送的消息、简单的自动回复、自定义菜单
- 粒子效果动画使用总结
- vscode 下载慢解决方法