回滚点

指的是设置一个标记,紧接着回滚到某个点,然后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);
}

}

}

原文地址:https://www.cnblogs.com/wangchuanfu/p/5561482.html