事务
事务(Transaction)就是为了保证数据完整性。
特性
- 原子性(Atomicity,或称不可分割性):
一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节 - 一致性(Consistency):
事务必须使数据库从一个一致性状态到另外一个一致性状态,一致性和原子性是密切相关的 - 隔离性(Isolation,又称独立性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,一个事务不能被其它事务所干扰
- 持久性(Durability):事务提交后,数据永久存在数据库中
传播属性(Propagation)
事务的传播属性是指在多个事务同时存在时,事务之间的处理关系
常 量 | 解释 |
---|---|
REQUIRED | 支持当前事务,如果不存在则创建新事务。类似于同名的EJB事务属性。这是事务注释的默认设置。 |
SUPPORTS | 支持当前事务,如果不存在事务,则以非事务方式执行。 |
MANDATORY | 支持当前事务,如果不存在则抛出异常。 |
REQUIRES_NEW | 创建一个新事务,如果存在当前事务,则挂起它。 |
NOT_SUPPORTED | 以非事务方式执行,如果当前事务存在,则挂起当前事务。内外事务为独立事务,互不影响 |
NEVER | 以非事务方式执行,如果存在事务,则抛出异常。 |
NESTED | 如果当前事务存在,则在嵌套事务中执行,否则就像REQUIRED一样。EJB中没有类似的功能。注意:嵌套事务的实际创建只在特定的事务上有效事务管理器。开箱即用,这只适用于JDBC DataSourceTransactionManager |
隔离级别(Isolation)
表示使用的事务隔离级别的级数
常 量 | 解 释 |
---|---|
DEFAULT | 设置底层数据存储的默认隔离级别。所有其他级别都对应于JDBC隔离级别。 |
READ_UNCOMMITTED | 一个常数,表示脏读、不可重复读和虚读可能发生的。此级别允许读取由一个事务更改的行提交该行中任何更改之前的另一个事务(“脏读”)。如果任何更改被回滚,则回滚第二个更改事务将检索到无效行。 |
READ_COMMITTED | 防止脏读的常数;不可重复读并可能发生幻像读取。此级别仅禁止事务从读取其中未提交更改的行开始。 |
REPEATABLE_READ | 表示脏读和不可重复读的常数预防;可能会发生幻像读取。此级别禁止事务禁止读取包含未提交更改的行,而且它也禁止这样做一个事务读取一行,另一个事务读取另一行的情况更改行,第一个事务将重新读取该行第二次读取的值不同(“不可重复读取”)。 |
SERIALIZABLE | 串行化,事务只能一个一个的执行,避免了脏读、不可重复读、幻读,执行效率低 |
- 脏读:一个事务对数据进行了增、删、改,但没有进行提交,另一个事务读取到该未提交的数据,此时第一个事务发生回滚,那么第二个事务读取到的数据就是脏数据
- 不可重复读:一个事务中发生两次读操作,在第一次读操作和第二次读操作之间,另一个数据对该条数据进行修改,那么这两条的数据是不对应的
- 幻读:第一个事务对一个范围内的数据进行修改,此事第二个事务在这个范围内新增一条数据,那么第一个事务修改的数据则会少一条
MySQL的默认隔离级别为 REPEATABLE_READ, SqlServer 和 Oracle 的默认隔离级别为 READ_COMMITTED
Spring Transactional 注意事项
- 在 @Transactional 中,默认异常回滚的级别为 RuntimeException