什么是事务?
事务是数据库保证原子性的一个重要的方式,事务可以是一句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框架去实现。业务开发者使用的时候需要指定事务管理器
事务的其他概念
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天,点击查看活动详情