Spring 事务的传播属性
所谓 spring 事务的传播属性, 就是定义在存在多个事务同时存在的时候, spring 应该如何处理这些事
务的行为。 这些属性在 TransactionDefinition 中定义, 具体常量的解释见下表:
常量名称 | 常量解释 |
PROPAGATION_REQUIRED | 支持当前事务, 如果当前没有事务, 就新建一个事 务。 这是最常见的选择, 也是 Spring 默认的事务 的传播。 |
PROPAGATION_REQUIRES_NEW | 新建事务, 如果当前存在事务, 把当前事务挂起。 新建的事务将和被挂起的事务没有任何关系, 是两 个独立的事务, 外层事务失败回滚之后, 不能回滚 内层事务执行的结果, 内层事务失败抛出异常, 外 层事务捕获, 也可以不处理回滚操作 |
PROPAGATION_SUPPORTS | 支持当前事务, 如果当前没有事务, 就以非事务方 式执行。 |
PROPAGATION_MANDATORY | 支持当前事务, 如果当前没有事务, 就抛出异常。 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作, 如果当前存在事务, 就把 当前事务挂起。 |
PROPAGATION_NEVER | 以非事务方式执行, 如果当前存在事务, 则抛出异常。 |
PROPAGATION_NESTED | 如果一个活动的事务存在, 则运行在一个嵌套的事 务中。 如果没有活动事务, 则按 REQUIRED 属性执 行。 它使用了一个单独的事务, 这个事务拥有多个 可以回滚的保存点。 内部事务的回滚不会对外部事 务造成影响。 它只对 DataSourceTransactionManager 事务管理器起效。 |
数据库隔离级别
隔离级别 | 隔离级别的值 | 导致的问题 |
Read-Uncommitted | 0 | 导致脏读 |
Read-Committed | 1 | 避免脏读, 允许不可重复读和幻读(默认的) |
Repeatable-Read | 2 | 避免脏读, 不可重复读, 允许幻读 |
Serializable | 3 | 串行化读, 事务只能一个一个执行, 避免了脏读、 不可重复读、 幻读。 执行效率慢, 使用时慎重 |
脏读: 一事务对数据进行了增删改, 但未提交, 另一事务可以读取到未提交的数据。 如果第一个事务这时候回滚了, 那么第 二个事务就读到了脏数据。
不可重复读: 一个事务中发生了两次读操作, 第一次读操作和第二次操作之间, 另外一个事务对数据进行了修改, 这时候两 次读取的数据是不一致的。
幻读: 第一个事务对一定范围的数据进行批量修改, 第二个事务在这个范围增加一条数据, 这时候第一个事务就会丢失对新增 数据的修改。
总结:
隔离级别越高, 越能保证数据的完整性和一致性, 但是对并发性能的影响也越大。
大多数的数据库默认隔离级别为 Read Commited, 比如 SqlServer、 Oracle
少数数据库默认隔离级别为: Repeatable Read 比如: MySQL InnoDB