事务的属性:
事务的熟悉:
1)propagation:用来设置事务的传播行为
事务的传播行为:一个方法运行在了一个开启了事务的方法中时,当前方法是使用原来的事务还是开启一个新的事务
—Propagation.REQUIRED:默认值,使用原来的事务
—Propagation.REQUIRES_NEW:将原来的事务挂起,开启一个新的事务
2)isolation:用来设置事务的隔离级别
事务的隔离级别:一个事务与其他事务隔离的程度称为隔离级别。隔离级别越高,数据一致性越好,但并发性越弱
背景是买书,当钱不够时回滚数据库
@Autowired
private BookService bookService;
@Transaction
public void checkOut(){
bookService.purchase();
}
@Transaction(propagation=Propagation.REQUIRES_NEW,isolation=Isolation.REPEATABLE_READ)
public void purchase(){}
purchase外面还有checkOut的事务
1)如果purchase的事务是REQUIRED传播行为:
当bookService的purchase()方法被另一个事务方法checkOut()调用时,它默认会在现有的事务内运行。这个默认的传播行为就是REQUIRED。因此在checkOut()方法的开始和终止边界内只有一个事务。这个事务只在checkOut()方法结束的时候被提交,结果用户一本书都买不了
2)REQUIRES_NEW传播行为
该方法必须启动一个新事务,并在自己的事务内运行。如果有事务在运行,就应该先挂起它。下面的结果时第一本书够钱能买,第二本不够钱买。而不是像1)的情况,第二本不够钱时全部回滚,第一本也买不了
事务的隔离级别
1)读未提交:READ UNCOMMITTED
允许Transaction01读取Transaction02未提交的修改
2)读已提交:READ COMMITTED(开发时通常使用的隔离级别
)
要求Transaction01只能读取Transaction02已提交的修改
3)可重复读:REPERTABLE READ
确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其他事务对这个字段进行更新
4)串行化:SERIALIZABLE
确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其他事务对这个表进行添加、更新、删除操作。可以避免任务并发问题,但性能十分低下
数据库事务并发问题
脏读:读取了更新后的值,而回滚后之前读取的值错误
不可重复读:读取了一个值,修改了之后再次读取,两次读取不一致(但要求是要一致)
幻读:读取了一部分,向表中插入新的,再次拂去,多出了一些行