Spring事务和事务传播机制
作者:小教学发布时间:2023-09-29分类:程序开发学习浏览:68
导读:Spring事务和事务传播机制1.什么是事务指的是一系列的操作或步骤,这些操作要么全部完成、要么全部不完成。对于数据库而言、一系列操作数据库的SQL语句就是一个事务,这些S...
Spring事务和事务传播机制
1.什么是事务
指的是一系列的操作或步骤,这些操作要么全部完成、要么全部不完成。对于数据库而言、一系列操作数据库的SQL语句就是一个事务,这些SQL语句只能同时执行成功或失败。
事务的特性:ACID
- 原子性:事务是不可分割的单位,一个事务中所有的操作要么成功、要么失败。
- 一致性:事务提交前后符合我们预设的规则,数据的完整性不能被破坏。(例如A有100元,B有100元,A向B转账了50元,A现在50元,B现在150元,它们总和是一致的)
- 隔离性:允许多个事务同时对数据进行读写的能力,隔离性可以防止多个事务交叉执行从而导致数据不一致的问题。
- 持久性:事务一旦被提交,对数据的修改就是永久的。
没有事务的隔离性可能会有什么问题?
- 脏读:事务A读取到了事务B还未提交的数据,但是B事务又进行了回滚,导致A事务读取到的数据是错误的。
- 不可重复读:一个事务两次查询的结果不同,在两次查询的过程中,有一个事务将数据修改了。
- 幻读:一个事务两次查询的结果集不同,在两次查询的过程中,有一个事务新增了一部分数据。
事务的隔离级别:
- 读未提交:一个事务可以看到还未被提交的事务数据。
- 读已提交:一个事务只能看到已经提交的事务数据,因此可以解决脏读问题。
- 可重复读:一个事务可以查看到其他事务已经提交的新插入记录,看不到其他事务对已有记录的更新,因此每次查询的结果都是相同的,可以解决不可重复读的问题。
- 序列化:事务最高隔离级别,他会强制将事务进行排序,因此事务就不会发生冲突,从而解决了脏读、不可重复读、幻读问题。
Spring事务的分类:
- 编程式事务(手动的进行创建、提交/回滚事务)
- 声明式事务(使用注解自动的实现事务的创建、提交/回滚)。
事务的操作流程:
- 开启事务(start transaction)
- commit(提交事务)
- rollback(回滚事务)
2.Spring编程式事务的实现
DataSourceTransactionManager是一个Spring的事务管理器,它使用数据源来管理事务。这个事务管理器在事务开始时,会得到一个数据库连接,允许事务的创建、提交/回滚。
TransactionDefinition 用于定义事务的特性,创建一个事务。
@SpringBootTest
class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Autowired
private DataSourceTransactionManager transactionManager;
@Autowired
private TransactionDefinition definition;
@Test
void addUser() {
//开启事务
TransactionStatus transactionStatus = transactionManager.getTransaction(definition);
//执行操作
int result = userMapper.addUser("mary","123",null);
System.out.println(result);
//提交事务
transactionManager.commit(transactionStatus);
//回滚事务
//transactionManager.rollback(transactionStatus);
}
}
3.声明式事务
@Transactional:
- 用于方法:只能应用再public方法上,表示进入方法时自动开启事务、结束方法时自动提交事务(方法内没有产生异常才会提交)
- 用于类:表示执行该类中的任一public方法,都会开启和提交事务。
public class UserController {
@Autowired
private UserMapper userMapper;
@Transactional(rollbackFor = Exception.class)
@RequestMapping("/add")
public int addUser(String username, String password, String avatar){
if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)){
return -1;
}
int result = userMapper.addUser(username, password, avatar);
try{
//捕获可能产生的异常...
}catch (Exception e){
//手动进行回滚
log.error(e.toString());
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return -2;
}
return result;
}
}
当方法对外抛出了异常,如果程序没有处理且抛出的异常和声明rollbackfor参数匹配,Spring会将这个事务标记为回滚。事务管理器最终会实现对这个事务的回滚。
@Transactional:注解的参数
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
//当存在多个事务管理器时指定使用哪一个事务管理器
@AliasFor("transactionManager")
String value() default "";
//当存在多个事务管理器时指定使用哪一个事务管理器
@AliasFor("value")
String transactionManager() default "";
String[] label() default {};
//事务的传播行为
Propagation propagation() default Propagation.REQUIRED;
//事务的隔离级别
Isolation isolation() default Isolation.DEFAULT;
//事务的超时时间,超时会自动进行回滚,默认值为-1表示没有超时时间,
int timeout() default -1;
String timeoutString() default "";
//指定事务是否为只读事务
boolean readOnly() default false;
//用于指定能够出发事务回滚的异常类型,可以指定多个异常类型
Class<? extends Throwable>[] rollbackFor() default {};
//用于指定能够出发事务回滚的异常类型,可以指定多个异常类型
String[] rollbackForClassName() default {};
//抛出指定的异常类型,不回滚事务
Class<? extends Throwable>[] noRollbackFor() default {};
//抛出指定的异常类型,不回滚事务
String[] noRollbackForClassName() default {};
}
4.Spring事务的隔离级别
- Isolation.DEFAULT:以连接的数据库的事务隔离级别为主。
- Isolation.READ_UNCOMMITTED:读未提交
- Isolation.READ_COMMITTED:读已提交
- Isolation.REPEATABLE_READ:可重复读
- Isolation.SERIALIZABLE:串行化
在Spring的声明式事务中,只需要将其配置在@Transaction注解中。
5.Spring事务的传播机制
主要解决一个多个事务相互调用时,事务是如何在这些方法间进行传播的以及它们之间的影响。
举一个例子:将购物车的商品支付购买
5.1事务的传播机制
- REQUIRED:默认的事务传播级别,表示如果当前存在事务,则加入该事务,如果当前没有事务,则创建一个新的事务。
- SUPPORTS:如何当前存在事务,则加入该事务,如果当前没有事务则以非事务的方式运行。
- MANDATORY:如果当前存在事务,则加入该事务,如果当前没有事务,则抛出异常。
- REQUIRE_NEW:如果当前存在事务,则把当前事务挂起,创建一个新事务,如果当前不存在事务,创建一个新事务。
- NOT_SUPPORTED:如果当前存在存在事务,则把当前事务挂起,以非事务方式运行。
- NEVER:如果当前存在事务,则抛出异常,不存在事务,以非事务方式运行。
- NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套来运行,如果当前没有事务,则和REQUIRED相同。
加入事务和嵌套事务:
- 加入事务可以理解为将当前事务的sql语句添加到上一个事务中。要么所有的SQL语句全部执行成功,要么都不执行。
非事务方式运行。 - NEVER:如果当前存在事务,则抛出异常,不存在事务,以非事务方式运行。
- NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套来运行,如果当前没有事务,则和REQUIRED相同。
加入事务和嵌套事务:
- 加入事务可以理解为将当前事务的sql语句添加到上一个事务中。要么所有的SQL语句全部执行成功,要么都不执行。
- 嵌套事务可以理解为将在当前事务内部再开启一个事务,如果进行回滚只能影响到自己,而不会影响到嵌套外的事务。但是嵌套事务和外部事务时一起提交的。也就是说外部事务可以影响内部事务的提交。
- 程序开发学习排行
-
- 1鸿蒙HarmonyOS:Web组件网页白屏检测
- 2HTTPS协议是安全传输,为啥还要再加密?
- 3HarmonyOS鸿蒙应用开发——数据持久化Preferences
- 4记解决MaterialButton背景颜色与设置值不同
- 5鸿蒙HarmonyOS实战-ArkUI组件(RelativeContainer)
- 6鸿蒙HarmonyOS实战-ArkUI组件(Stack)
- 7鸿蒙HarmonyOS实战-ArkUI组件(GridRow/GridCol)
- 8[Android][NDK][Cmake]一文搞懂Android项目中的Cmake
- 9鸿蒙HarmonyOS实战-ArkUI组件(mediaquery)
- 最近发表
-
- WooCommerce最好的WordPress常用插件下载博客插件模块的相关产品
- 羊驼机器人最好的WordPress常用插件下载博客插件模块
- IP信息记录器最好的WordPress常用插件下载博客插件模块
- Linkly for WooCommerce最好的WordPress常用插件下载博客插件模块
- 元素聚合器Forms最好的WordPress常用插件下载博客插件模块
- Promaker Chat 最好的WordPress通用插件下载 博客插件模块
- 自动更新发布日期最好的WordPress常用插件下载博客插件模块
- WordPress官方最好的获取回复WordPress常用插件下载博客插件模块
- Img to rss最好的wordpress常用插件下载博客插件模块
- WPMozo为Elementor最好的WordPress常用插件下载博客插件模块添加精简版