重温一下Spring的事务

110 阅读3分钟

什么是事务?

事务是数据库保证原子性的一个重要的方式,事务可以是一句SQL或者一组SQL,事务是数据库操作的最小单元,要么成功,要么失败。

spring中使用注解

在spring中有两种使用方式来使用事务:
1、使用@Transactional注解
在需要开启事务的方法或者类上添加注解

@Transactional

2、使用编程式的方式

// 1、获取事务管理器
DataSourceTransactionManager bean = daoHelper.getBean(DataSourceTransactionManager.class);
// 2、获取事务定义
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// 3、设置事务传播行为,开启新事务
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);

spring中事务实现的原理

原理其实很简单,就是通过aop在sql执行的前后添加begin,和commit等。

spring提供了一个AbstractPlatformTransactionManager抽象类供各orm框架去实现。业务开发者使用的时候需要指定事务管理器

image.png

事务的其他概念

1、事务的隔离级别
  • read-uncommited 读未提交(会带来的问题:脏读,重复读、幻读)
  • read-commited 读已提交(避免脏读)
  • repeatable-read 可重复读(避免脏读和重复度)
  • searilizedable 串行的(相当于单线程,可以解决所有问题,但是慢)
2、事务的传播机制
  • require 创建新的事务
  • require-new 创建新的事务
  • nested 嵌套事务,嵌套事物指的是一个大事物中包含小事物,利用的是数据库的回滚点机制,遇到问题可以回滚到指定点,但是事物提交要依赖于大事物的提交。
  • never 永远不需要当前存在事务

还有一些其他传播机制

3、事务失效的场景
  • 添加事务注解的类不是由spring托管的
  • 添加事务的方法不是public修饰的,因为事务时基于aop实现的,aop是利用cglib的代理技术来实现的,如果不是指定public,将没有权限操作类,也就是生成不了代理类。
  • 添加事务的方法,异常被捕获
  • 添加事务的方法抛出的是检查异常(检查异常:FileNotFoundException, SqlException,IOException等)
  • 自定义切面顺序导致失效
  • 用final修饰的方法 原因:还是代理的原因,如果用final修饰了,代理类不能重写方法织入事务代码
  • 用static修饰的方法 原因同上
  • 多线程下事务失效,原因是数据库连接是放在ThradLocal中的,多线程下获取的connect是不一样的。
  • 错误的指定传播机制 比如指定了never
  • 使用的数据库不支持事务,比如mysql的myIsam引擎
  • 数据源没有配置事务管理器

综上:事务失效其实就是两点 1、aop不能正常织入的、代码执行异常引发的。

分布式事务

什么情况下会产生分布式事务?比如异构数据库、或者分库分表都会涉及到分布式事务。涉及到分布式事务一般就会讲到分布式事务一致性。

分布式事务一致性解决方式

1、JPA方式 2、XA方式

还有其他方式,下一篇详细讲解一下,这些分布式事务一致性的使用方法。

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第21天,点击查看活动详情