数据库相关知识

181 阅读2分钟

为了我们更好地了解@Transaction的内容,先复习一下数据库的基本特性:

一 数据库事务ACID特性

  1. 原子性:整个事务的所有操作,要么全部完成,要么全部失败,没有中间的过程。事务在执行过程中发生错误,将会被回滚到事务开始前的状态。就想这个事务从未发生过一样。
  2. 一致性:整个事务可以改变封装状态(除非是只读状态),事务必须保持系统处于同一个状态,不管给任何给定的时间并发事务有多少。
  3. 隔离型:指的是两个事务之间的隔离程度。
  4. 持久性:指的是事务完成之后,该事务对数据库所做的改变是持久性的保持在数据库中,并不会发生回滚。

二 隔离级别

我们把隔离级别定位为4层,分别是:脏读( dirty read ), 读/写提交( read commit ), 可重复读( repeatable read ),序列化( Serializable)。

  1. 脏读: 最低的隔离级别,允许一个事务去读取另外一个事务中为提交的数据。
  2. 读写提交: 一个事务只能读取另外一个事务已经提交的数据。
  3. 可重复读: 针对的是数据库同一条记录而言的,可重复读会使得同一条数据库记录的读/写按照一个序列化进行操作,不会产生交叉情况。
  4. 序列化: 让SQL按照顺序读写的方式,能够消除数据库事务之间并发产生数据不一致的问题。

三 选择隔离级别和传播行为

在互联网应用中,不仅要考虑数据库的一致性,还要整体考虑系统的性能,一般来说,从脏读到序列化,系统性能直线下降,因此设置高的级别,例如序列化,会严重压制并发量,从而引起大量的线程鼓起,直到获得锁才能进一步操作。因此在购物类应用中,通过隔离级别控制数据一致性的方式被排除,脏读风险太大。企业会主动选择读写提交方式来设置业务,有助于提高并发量,也能压制脏读

// mysql 默认的是可重复读。oracle默认是读写提交。
// mysql支持四种隔离级别,oracle只支持读写提交和序列化。
@Autowired
private RoleDao roleDao = null;
// 设置方法为读写提交的隔离级别  
@Transaction( propagation=propagation.REQUIRED,isolation=Isolation.READ_COMMITTED )
public int insertRole(Role role){
	return roleDao.insert(role);
}

Spring的7种传播行为