什么是事务?
简单用一句话来说的话就是:一组业务操作ABCD,要么全部成功,要么全部不成功。
事务的特性:ACID
-
原子性:整体
-
一致性:完成
-
隔离性:并发
-
持久性:结果
事务的隔离级别: -
脏读:一个事务读到另一个事务没有提交的数据
-
不可重复读:一个事务读到另一个事务已提交的数据(update)
-
虚读(幻读):一个事务读到另一个事务已提交的数据(insert)
隔离级别: -
read uncommitted:读未提交。存在3个问题
-
read committed:读已提交。解决脏读,存在2个问题
-
repeatable read:可重复读。解决:脏读、不可重复读,存在1个问题。
-
serializable :串行化。都解决,单事务。
在之前我们学习JDBC操作的时候的事务是这样的:
ABCD 一个事务
Connection conn = null;
try{
//1 获得连接
conn = ...;
//2 开启事务
conn.setAutoCommit(false);
A
B
C
D
//3 提交事务
conn.commit();
} catche(){
//4 回滚事务
conn.rollback();
当然我们也可以通过保存点的方式来进行事务管理:
举例来说:AB是每月还花呗的操作,CD就是成功换完当月花呗后发送的短信操作。我们可以在先开启事务,如果是AB出错,我们可以直接进行回滚。如果是CD出错,我们就可以在AB后面设置一个保存点,当CD错误后,可以通过判断保存点的值来进行回滚操作。
就好比:我们成功换完当月的花呗后,不知道短信是因为欠费还是什么原因出现的无法成功发送短信到手机的操作。这时候花呗反正已经成功进行完成,而短信操作对于我们整件事来说是可有可无的,当然有是最好的,但是不会影响整个事件的操作。
需求:AB(必须),CD(可选)
Connection conn = null;
Savepoint savepoint = null; //保存点,记录操作的当前位置,之后可以回滚到指定的位置。(可以回滚一部分)
try{
//1 获得连接
conn = ...;
//2 开启事务
conn.setAutoCommit(false);
A
B
savepoint = conn.setSavepoint();
C
D
//3 提交事务
conn.commit();
} catche(){
if(savepoint != null){ //CD异常
// 回滚到CD之前
conn.rollback(savepoint);
// 提交AB
conn.commit();
} else{ //AB异常
// 回滚AB
conn.rollback();
}
}