在事务处理的过程中,我们可能并不需要回滚所有的内容,而只是需要回滚其中一部分,这就需要设立事务的保存点作为标志。
具体代码如下(测试成功):
package cn.itcast.jdbc; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Savepoint; import java.sql.Statement; import org.junit.Test; /** * 测试JDBC事务 */ public class SavePointTest { /** * 测试事务 * @throws SQLException */ @Test public void testSavePoint() throws SQLException { savePointTest(); } /** * 测试事务 * @throws SQLException */ static void savePointTest() throws SQLException { Connection conn = null; Statement st = null; ResultSet rs = null; //声明事务的保存点 Savepoint sp = null; try { conn = JdbcUtils.getConnection(); //开启事务 conn.setAutoCommit(false); st = conn.createStatement(); String sql = "update user set money = money - 10 where id = 1"; st.executeUpdate(sql); //设立事务保存点 sp = conn.setSavepoint(); sql = "update user set money=money-10 where id=3"; st.executeUpdate(sql); sql = "select money from user where id=2"; rs = st.executeQuery(sql); float money = 0.0f; if(rs.next()) { money = rs.getFloat("money"); } if(money > 300) { //假设这里抛异常,如果不加事务回滚,第一条SQL会执行成功 throw new RuntimeException("已经超过最大值!"); } sql = "update user set money=money+10 where id=2"; st.executeUpdate(sql); //提交事务 conn.commit(); } catch (RuntimeException e) { if (conn != null && sp != null) { //这里只是回滚到保存点,然后提交事务 conn.rollback(sp); conn.commit(); } throw e; } catch (SQLException e) { //如果发生SQL异常,则让事务回滚 if(conn != null) { //回滚所有的操作 conn.rollback(); } throw e; } finally { JdbcUtils.free(rs, st, conn); } } }