回滚点
指的是设置一个标记,紧接着回滚到某个点,然后commit,但是,标记之前的事务是你想要的,
package cn.itcast.transaction;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;
import org.junit.Test;
import cn.itcast.utils.JdbcUtils;
/*
* jdbc 程序去管理事务
*
* 注意: 在编写jdbc的管理事务的程序时,要明确如下两点:
*
* 1.管理事务的时候, 必须 是同一个connection 对象
* 2.由于 事务 比较严谨, 所以在管理事务的时候, 出现了任何的异常 都回滚 , 那么就需要将异常放大到最大化.
*
*/
public class TransactionTest {
//模拟 着 aaa----bbb 转账 100 块钱 ----- 两条sql语句, aaa的账户 减去100, bbb的账户 加上100
@Test
public void test1(){
Connection conn = null;
PreparedStatement stmt= null;
try {
conn = JdbcUtils.getConnection();
//开启事务
conn.setAutoCommit(false); // 这就相当于 开启事务, start transaction
stmt = conn.prepareStatement("update account set money=money-100 where name='aaa'");
stmt.executeUpdate();
int i =1/0;
stmt = conn.prepareStatement("update account set money=money+100 where name='bbb'");
stmt.executeUpdate();
//提交事务
conn.commit();
// } catch (SQLException e) {
} catch (Exception e) {
try {
//回滚事务
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}finally{
// 释放资源
JdbcUtils.release(null, stmt, conn);
}
}
// 模拟: ccc向 bbb借钱, 由于bbb和ccc的关系很不错, 而bbb又 没钱, 那么bbb决定先找 aaa借 100, 然后在借给 ccc
// 这种场景下: 会有几条 sql 语句? 会有 4 条 sql 语句 , 首先 会有 aaa向bbb 转账的过程,然后 又有 bbb 向 ccc转账的过程
//这个时候, 由于 aaa向bbb 转账是一个小单元, 而 bbb向ccc又 是一个小单元, 如果 aaa 向bbb转账成功, 而 bbb向ccc转账失败, 那么如果
// 按照之前的有任何异常都 回滚到原始状态, 那么 觉得 有点浪费, 因为 aaa向bbb转账成功, 那么希望下次可以接着之前操作继续往下走.
// 所以这个时候 就 引入了设置回滚点的 知识 .
// 回滚点指的是 设置一个标记. 紧接着 回 滚 到某个点,然后 在commit ,这样 可以将 开启事务到 标记之间的所做的操作确认, 持久化到硬盘上.
//注意: 设置回滚点的时候, 你得 在你认为 合适的地方去设置, 不能 乱搞
// 设置 回滚点的时候 要根据程序的具体的逻辑需求, 合适的地方设置.
// 设置回滚点 就像 大家玩 游戏的 是 存了 档, 下次 可以继续 之前的玩...
@Test
public void testSavePoint(){
Connection conn = null;
PreparedStatement stmt = null;
Savepoint sp = null;
try {
conn =JdbcUtils.getConnection();
//开启事务
conn.setAutoCommit(false); //start transaction;
sp = conn.setSavepoint();
stmt = conn.prepareStatement("update account set money=money-100 where name='aaa'");
stmt.executeUpdate();
// int j=1/0;
stmt = conn.prepareStatement("update account set money=money+100 where name='bbb'");
stmt.executeUpdate();
sp = conn.setSavepoint(); //设置一个回滚点
int i =1/0;
stmt = conn.prepareStatement("update account set money=money-100 where name='bbb'");
stmt.executeUpdate();
stmt = conn.prepareStatement("update account set money=money+100 where name='ccc'");
stmt.executeUpdate();
sp = conn.setSavepoint(); //设置一个回滚点
} catch (Exception e) {
try {
conn.rollback(sp); //回滚到 设置回滚点.
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}finally{
//提交事务
try {
conn.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//释放资源
JdbcUtils.release(null, stmt, conn);
}
}
}