这篇文章主要介绍了Spring事物基础知识及AOP相关陷阱,在平时的实际开发中经常会遇到,只有深入了解了其中的原理,才会在工作中能够有效应对
一、事务的定义
事务(Transaction),是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit),是恢复和并发控制的基本单位。
事务的产生,其实是为了当应用程序访问数据库的时候,事务能够简化我们的编程模型,不需要我们去考虑各种各样的潜在错误和并发问题.
二、事务的属性
事务具有4个属性,简称 ACID
属性 | 说明 | |
---|---|---|
Atomicity | 原子性 | 一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。 |
Consistency | 一致性 | 事务执行的结果必须是使数据库从一个一致性状态c0变到另一个一致性状态c1 |
Isolation | 隔离性 | 一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。 |
Durability | 持久性 | 指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。 |
三、Spring 事务的隔离级别
当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性。
在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种问题
3.1 隔离级别引出的问题
3.1.1 脏读
是指在没有隔离的情况下,一个事务读取了另外一个事务已修改但未提交(有可能回滚也有可能继续修改)的缓冲区数据。
3.1.2 不可重复读
数据库中的某项数据在一个事务多次读取,但是在多次读取期间,其他事务对其有修改并提交,导致返回值不同,这就发生了不可重复读。
不可重复读侧重修改。
3.1.3 幻读
幻读和不可重复读相似。当一个事务(T1)读取几行记录后(事务并没有结束),另一个并发事务(T2)插入了一些记录时,幻读就发生了。在后来的查询中,第一个事务(T1)就会发现一些原来没有的额外记录。
幻读侧重新增或者删除。
3.2 隔离级别
在理想状态下,事务之间将完全隔离(即下表中的 Isolation.SERIALIZABLE ),从而可以防止这些问题发生。
然而,完全隔离会影响性能,因为隔离经常涉及到锁定在数据库中的记录(甚至有时是锁表)。
完全隔离要求事务相互等待来完成工作,会阻碍并发。因此,可以根据业务场景选择不同的隔离级别。
隔离级别 | 含义 |
---|---|
Isolation.DEFAULT | 使用后端数据库默认的隔离级别 |
Isolation.READ_UNCOMMITTED | 允许读取尚未提交的更改。可能导致脏读、幻读或不可重复读。 |
Isolation.READ_COMMITTED | (Oracle 默认级别)允许从已经提交的并发事务读取。可防止脏读,但幻读和不可重复读仍可能会发生。 |
Isolat |