事务
事务是逻辑上的一组操作,要么都执行,要么都不执行。
事务的特性
- 原子性: 事务是最小单位,不允许分割,就是保证了事务的动作要么全部完成,要么不做。
- 一致性: 执行事务前后,数据保证一致,多个事务对同一个数据读取的结果是相同的。
- 隔离性: 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的。
- 持久性: 一个事务被提交之后,他对数据库的改变是持久的。
并发事务所带来的问题
- 脏读(Dirty read): 当一个事务正在访问数据并对其修改后,但是这种修改还没有提交到数据库,另一个事务也访问了这个数据,因为这个数据还没有提交。就称为这种数据是“脏数据”,这种行为就是脏读。
- 丢失修改(Lost to modify): 指在一个事务读取一个数据时,另一个事务也访问了这个数据,那么在第一个事务修改之后,第二个事务也修改了这个数据,那么第一个事务修改的结果就丢失了,称为丢失修改。
- 不可重复读(Unrepeatableread): 指在一个事务内多次读同一数据。在这个事务还没结束时,另一个事务也访问该数据。那么第一个事务两次读到的数据不一样。称为不可重复读。
- 幻读(Phantom read): 幻读和不可重复读类似。也是在一个事务两次访问之间,另一个事务插入(删除)了一部分数据,导致两次读取的结果不一致,像幻觉一样,称为幻读。
不可重复读和幻读的区别: 不可重复读重点是修改,幻读是增加或者删除
事务的隔离级别
- READ-UNCOMMITTED(读未提交):最低的隔离级别,就是允许读没有提交的数据变更,所有问题都可能发生。
- READ-COMMITTED(读已提交):允许读取事务已经提交的数据,可以阻止脏读。但是幻读和不可重复读还不能避免。
- REPEATABLE-READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据是被本身事务所修改。可以阻止脏读和不可重复读。幻读还是会发生。
- SERIABLIZABLE(可串行化):最高的隔离级别,符合所有特性,不存在任何问题,就是效率低。
Spring中事务
Spring开始事务使用注解@EnableTransactionManagment开启事务,Spring中规定了7中事务的传播行为,增强了事务的特性,还有5种隔离级别。
传播行为
事务的传播行为是描述由某一个事务传播行为修饰的方法被嵌套进另一个方法的时事务如何传播。
- PROPAGATION_REQUIRED: 如果当前没有事务,就新建一个,如果有就加入到这个事务。
- PROPAGATION_SUPPORTS: 支持当前事务,如果当前没有事务,就以非事务方式执行。
- PROPAGATION_MANDATORY: 使用当前事务,如果没有事务,就抛出异常
- PROPAGATION_REQUIRES_NEW: 新建事务,如果当前存在事务,把当前事务挂起。
- PROPAGATION_NOT_SUPPORTED: 以非事务方式执行操作,如果存在当前事务,把事务挂起
- PROPAGATION_NEVER: 以非事务方式执行,如果当前存在事务,则抛出异常
- PROPAGATION_NESTED: 如果当前存在事务,则在嵌套事务中执行,如果没有,则新建。
隔离属性
- ISOLATION_DEFAULT:使用数据库默认的。
- ISOLATION_READ_UNCOMMITTED
- ISOLATION_READ_COMMITTED
- ISOLATION_UNREPEATABLE_READ
- ISOLATION_SERIALIZABLE