事务是关系型数据库的重要概念,指的是一组原子性的操作,要么全部执行成功,要么全部失败。

事务的ACID特性

A:Atomicity - 原子性,包含在一个事务中的一组操作是原子性的,要么全部执行成功,要么全部失败。
C:Consistency - 一致性,一个事务在执行过程中确保数据库从一个一致性状态向另外一个一致性状态转换,不会出现中间的不一致状态。
I:Isolation - 隔离性,一个事务中的修改在提交以前,对其他事务不可见。
D:Durability - 持久性,一个事务一旦提交就永久生效。

事务的隔离级别

事务隔离性其实非常复杂,而要达到一个事务的修改在提交以前对其他事务不可见这一隔离目标的难度也非常大,其实隔离性应该是“对不可见程度”的描述。隔离性越好则越不可见或者仅仅在极少数情况下可见,而隔离性不好则可能干脆就是“可见”或者在大部分情况下都“可见”。好的隔离性一般来讲是需要牺牲性能来实现的。

隔离级别就是描述这种“可见性”的,是为了平衡事务隔离性和并发性能之间的关系而规定的并发事务之间的隔离程度。包括以下四种:

  1. READ UNCOMMITTED:未提交度
    指一个事务的修改在未提交之前,对其他事务也是可见的,也被称为脏读(Dirty Read)。这个隔离级别会导致很多问题,因为未提交事务的修改很有可能被当前事务回滚,这意味着其他事务读取到了并不会生效的脏数据。而且,与其他隔离级别相比,READ UNCOMMITTED在性能上也不会有太多改善,因此,在实际应用中很少使用,我们在实际应用中应该尽量避免使用。
  2. READ COMMITED:提交读
    当前事务只能“看到”其他事务的已提交数据,提交读可以避免脏读,也是大部分数据库的缺省隔离级别(但MYSQL不是),这个隔离级别又叫不可重复度(norepeatable read),因为同一个事务中两次执行同样的查询,可能会得到不一样的结果。
  3. REPEATED READ:可重复度
    保证同一个事务中多次执行同一查询得到相同的结果,可重复读解决了脏读和不可重复读的问题。但是,可重复读存在幻读(phantom read)的问题:一个事务中读取某一范围数据后,事务提交前,另外一个事务在该范围内插入了数据,所以当前一事务再次读取该范围数据时,会产生“幻影行”。Mysql的InnoDB引擎引入MVCC(多版本并发控制 multiversion concurrency control)解决了幻读问题。
  4. SERIALIZABLE:可串行化
    可串行化是最高隔离级别,是牺牲并发性能强化隔离性、提高数据一致性的解决方案,可串行化通过强制事务串行执行来避免幻读问题。

应用通过数据库链接connection控制控制事务,connection有关事务的操作包括autocommit/commit/rollback:通过autocommit=false启动事务,通过commit提交事务,rollback回滚事务。

Spring框架的事务最终也是通过数据库connection的上述操作实现的,具体细节后面会一步一步学习。

上一篇 动态代理 java原生 vs Cglib
下一篇 Spring事务传播机制


45 声望17 粉丝