1.什么是事务
事务是访问数据库的一个操作序列,数据库应用系统通过事务来完成对数据库的存取。事务的正确执行使得数据库从一个状态转换为另一个状态
事务有 ACID 的原则:
原子性(atomicity):即不可分割,事务要么全部被执行,要么全部不被执行,如果事务中所有的子事务全部提交成功,则所有的数据库操作都被提交,数据库状态会发生变化;如果有子事务失败,则其他子事务的数据库操作全部被回滚,数据库回到执行事务之前的状态,不回发生状态变化
一致性(consistency):事务的执行使数据库从一种正确状态转换为另一种正确状态
隔离性(isolation):在事务正常提交之前,不允许把该事务对数据库数据的任何改变提供给其他事务,即在事务正确提交之前,它可能的结果对其他事务不可见
持久性(durability):事务正确提交之后,其结果将永远保存在数据库中,即使在事务提交之后有了其他故障,事务的处理结果也会得到保存
2.并发下事务会产生的问题
脏读:事务 A 读到了事务 B 还没有提交的数据
幻读:一个事务在前后两次查询同一范围的时候,后一次查询看到了前一次查询没有看到的行
不可重复读:事务 A 首先读取了一条数据,执行逻辑的时候,事务 B 将这条数据改变了,然后事务 A 再次读取的时候,发现数据不匹配了
3.Spring 事务的隔离级别
default:默认隔离级别,Spring 将使用数据库默认的隔离级别
read_uncommitted:读未提交,能够读取到没有被提交的数据,导致脏读,幻读,不可重复读
read_committed:读已提交,能够读取到已经被提交的数据,能解决脏读,导致幻读和不可重复读
repeatable_read:重复读取,即在数据读出来之后加锁,解决了脏读,不可重复读,无法解决幻读
serializable:串行化,最高的事务隔离级别,解决了以上所有问题,性能差,行级锁
mysql 默认的事务隔离级别是 repeatable_read
4.Spring 事务传播机制
REQUIRED:支持当前事务,如果没有事务会创建一个新的事务
REQUIRED_NEW:挂起当前事务,创建一个新的事务
MANDATORY:支持当前事务,如果当前不存在事务则抛出异常
SUPPORTS:支持当前事务,如果当前没有事务会以非事务方式执行
NOT_SUPPORTED:以非事务方式执行,如果当前存在事务则将当前事务挂起
NESTED:如果当前存在事务,则在嵌套事务内执行,如果当前不存在事务,则会创建一个新的事务
NEVER:以非事务方式执行,如果当前存在事务抛出异常
Spring @Transactionl 注解什么时候失效
在 spring aop 代理下,只有目标方法被外部调用,目标方法才由 spring 生成的代理对象来管理,这会造成自调用问题
若同一类中的其他方法没有@Transactionl 注解的方法内部调用有@Transactionl 注解的方法,有@Transactionl 注解的方法的事务会被忽略,不会发生回滚
@Transactional 只能被应用到 public 方法上