事务的传播属性
当事务方法被另一个事务方法调用时, 必须指定事务应该如何传播。例如: 方法可能继续在现有事务中运行, 也可能开启一个新事务, 并在自己的事务中运行;
事务的传播行为可以由传播属性指定;Spring 定义了7种类传播行为;
传播属性 | 描述 |
---|---|
REQUIRED(常用) | 如果有事务在运行,当前的方法就在这个事务内运行,否则,就启动一个新的事务,并在自己的事务内运行,也是spring传播属性的默认值 |
REQUIRED_NEW(常用) | 当前的方法必须启动新事务,并在它自己的事务内运行;如果有事务正在运行,应该将它桂起 |
SUPPORTS | 如果有事务在运行,当前的方法就在这个事务内运行;否则它可以不运行在事务中 |
NOT_SUPPORTEI | 当前的方法不应该运行在事务中;如果有运行的事务,将它桂起 |
MANDATORY | 当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常 |
NEVER | 当前的方法不应该运行在事务中;如果有运行的事务,就抛出异常 |
NESTED | 如果有事务在运行,当前的方法就应该在这个事务的嶔嵌套事务内运行;否则,就启动一个新的事务,并在它自己的事务内运行 |
事务传播属性的设置:
@Transaction(propagation=“Propagation.事务”)
事务的隔离级别
数据库并发问题:
-
脏读
1、TransactionOl将某条记录的AGE值从20修改为30;
2、Transaction02读取了TransactionOl更新后的值:30;
3、TransactionOl回滚了AGE值恢复到20;
4、Transaction02读取到的30就是一个无效的值。 -
不可重复读
1、TransactionOl读取了AGE值为20;
2、Transaction02将AGE值修改为30;
3、TransactionOl再次读取AGE值为30,和第一次读取不一致。 -
幻读
1、TransactionOl读取了STUDENT表中的一部分数据;
2、Transaction02向STUDENT表中插入了新的行;
3、Transaction02读取了STUDENT表时多出了一些行;
数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响.避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别。 SQL标准中规定了多种事务隔离级别;不同隔离级别对应不同的干扰程度,隔离级别越高.数据一致性就越好,但并发性越弱。
-
读未提交:READ UNCOMMITTED
允许Transaction0l读取Transaction02未提交的修改。 -
读己提交:READ COMMITTED
要求Transaction0l只能读取Transaction02己提交的修改。 -
可重复读:REPEATABLE READ
确保Transaction0l可以多次从一个字段中读取到相同的值,即TransactionOl执行期间禁止其它事务对这个字段进行更新。 -
串行化:SERIALIZABLE
确保Transaction0l可以多次从一个表中读取到相同的行。在Transaction0l执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。
各个级别解决并发问题的能力
脏读 | 不可重复读 | 幻读 | |
---|---|---|---|
Read uncommitted | √ | √ | √ |
Read committed | × | √ | √ |
Repeatable read | × | × | √ |
Serializable | × | × | × |
Oracle和Mysql对事务隔离级别的支持程度
Oracle | Mysql | |
---|---|---|
Read uncommitted | × | √ |
Read committed(开发时通常使用的隔离级别) | √(默认) | √ |
Repeatable read | × | √(默认) |
Serializable | √ | √ |
事务的隔离级别的设置:
@Transaction(isolation=“Isolation.隔离级别”)