JDBC | 第四章:事务提交与回滚

Transaction-JDBC管理

JDBC默认是自动事务:
执行sql语句:executeUpdate() ---- 每执行一次executeUpdate方法 代表 事务自动提交
所以需要通过jdbc的API手动事务:
开启事务:conn.setAutoCommit(false);
提交事务:conn.commit();
回滚事务:conn.rollback();
注意:控制事务的connnection必须是同一个
执行sql的connection与开启事务的connnection必须是同一个才能对事务进行控制。

Transaction示例:

import java.sql.*;

public class Jdbc {

    public static final String URL = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
    public static final String USER = "root";
    public static final String PASSWORD = "123456";


    public static void main(String[] args) throws Exception {
        //1.加载驱动程序
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2. 获得数据库连接
        Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
        //3.操作数据库,实现增删改查
        String sql = "insert into class (id, teacher_id) values (?,?)";
        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        try {
            //设置事务自动提交为手动提交
            conn.setAutoCommit(false);
            for (int i = 20; i < 30; i++) {
                preparedStatement.setObject(1, i);
                preparedStatement.setObject(2, i);
                preparedStatement.addBatch();
            }
            int [] success = preparedStatement.executeBatch();
            System.out.println(success.length);
            //手动制造异常
            int m = 10 / 0;
            for (int i = 30; i < 40; i++) {
                preparedStatement.setObject(1, i);
                preparedStatement.setObject(2, i);
                preparedStatement.addBatch();
            }
            int [] success2 = preparedStatement.executeBatch();
            System.out.println(success2.length);
            //提交事务
            conn.commit();

        }  catch (Exception e) {
            e.printStackTrace();
            try {
                conn.rollback();
                System.out.println("JDBC Transaction rolled back successfully");
            } catch (SQLException e1) {
                System.out.println("SQLException in rollback" + e1.getMessage());
                e1.printStackTrace();
            }

        } finally {
            //执行完数据库操作后记得关闭数据库连接资源
            try {
                preparedStatement.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }

    }
}

异常信息:

JDBC Savepoint

有时候一个事务可能是一组复杂的语句,因此可能想要回滚到事务中某个特殊的点。JDBC Savepoint帮我们在事务中创建检查点(checkpoint),这样就可以回滚到指定点。当事务提交或者整个事务回滚后,为事务产生的任何保存点都会自动释放并变为无效。把事务回滚到一个保存点,会使其他所有保存点自动释放并变为无效。

步骤:

1.在事务中创建检查点

2.异常中捕捉检查点并回滚到检查点

Savepoint示例:

import cn.hutool.core.util.StrUtil;
import java.sql.*;

public class Jdbc {

    public static final String URL = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
    public static final String USER = "root";
    public static final String PASSWORD = "123456";


    public static void main(String[] args) throws Exception {
        //1.加载驱动程序
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2. 获得数据库连接
        Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
        //3.操作数据库,实现增删改查
        String classSql = "insert into class (id, teacher_id) values (?,?)";
        String userSql = "insert into users (name, age) values (?,?)";
        Savepoint savepoint = null;

        try {
            //设置事务自动提交为手动提交
            conn.setAutoCommit(false);
            PreparedStatement preparedStatement1 = conn.prepareStatement(classSql);
            for (int i = 20; i < 30; i++) {
                preparedStatement1.setObject(1, i);
                preparedStatement1.setObject(2, i);
                preparedStatement1.addBatch();
            }
            int [] success = preparedStatement1.executeBatch();
            System.out.println(success.length);
            //设置回滚的点  失败只会回滚users信息
            savepoint = conn.setSavepoint("检查点");
            //手动制造异常
            int m = 10 / 0;
            PreparedStatement preparedStatement2 = conn.prepareStatement(userSql);
            preparedStatement2.setObject(1, "腕豪");
            preparedStatement2.setObject(2, "24");
            preparedStatement2.executeUpdate();
            //提交事务
            conn.commit();

        }  catch (Exception e) {
            e.printStackTrace();
            if (StrUtil.isEmptyIfStr(savepoint)) {
                //回滚所有更新sql
                conn.rollback();
                System.out.println("JDBC Transaction rolled back successfully");
            } else {
                //回滚到指定位置
                conn.rollback(savepoint);
                System.out.println("JDBC Transaction rolled back successfully");
                conn.commit();
            }

        } finally {
            //执行完数据库操作后记得关闭数据库连接资源
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }

    }
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值