JDBC中事务及事务中保存点的使用(Transaction&Savepoints)

10 篇文章 0 订阅


有关事务的相关知识点可阅读文章:SQL完整性、多表查询及事务

JDBC中的事务

事务能够控制是否和何时更改应用于数据库,将单个SQL语句或一组SQL语句视为一个逻辑单元,如果任何语句失败,则整个事务将失败

JDBC驱动程序默认使用自动提交模式,每个SQL语句在完成后都会提交到数据库

  • 启用手动事务支持:
    使用Connection对象的setAutoCommit()方法
    如果将boolean false传递给setAutoCommit()则关闭自动提交,可以通过传递布尔值true重新打开它

事务的提交和回滚

事务默认使用自动提交模式

启用手动事务支持:

  • 将false传递给setAutoCommit()关闭自动提交
connection.setAutoCommit(false);//关闭自动提交事务
  • 完成更改后,在连接对象上调用commit()方法提交事务
connection.commit();//手动提交事务
  • 如果不提交事务或者发生错误,则进行回滚更新
connection.rollback();

代码示例:

 public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        try {
            //1加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2获得链接
            String userName = "root";
            String passWord = "123456";
            String url = "jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT";
            connection = DriverManager.getConnection(url, userName, passWord);
            connection.setAutoCommit(false);//关闭自动提交事务
            //3定义sql,创建状态通道(进行sql语句的发送)
            statement = connection.createStatement();
            //4执行增删改查
            int result = statement.executeUpdate("insert into student values(9,'哈哈','3')");
            connection.commit();//手动提交事务
            //返回结果为受影响的行数
            if(result > 0){
                System.out.println("执行成功");
            }else{
                System.out.println("执行失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            try {
                connection.rollback();//如果出现异常,则回滚
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }finally {
            try {
                //5关闭资源
                if(statement != null){
                    statement.close();
                }
                if(connection != null){
                    connection.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }//end finally
    }

某些业务逻辑需要同时成功or同时失败,因此需要设置手动提交事务,此时某些业务发生异常后不能进行事务提交,这是事务的意义

该事务案例可阅读文章:JDBC事务案例——转账


保存点Savepoints

Savepoint接口提供了额外的事务控制

设置保存点时,可以在事务中定义逻辑回滚点,如果发生异常,则可以使用回滚方法来撤消所有更改仅保存在保存点之前所做的更改

Connection对象有两种新的方法管理保存点 :

方法描述
setSavepoint(String savepointName)定义新的保存点,返回一个Savepoint对象
releaseSavepoint(Savepoint savepointName)删除保存点,tips:需要一个Savepoint对象作为参数,此对象通常是由setSavepoint()方法生成的保存点

代码示例:

在执行insert操作之后添加会抛出异常的语句System.out.println(1/0);使事务进行catch中的rollback操作,由于事务具有原子性,因此result1和result2都不执行,代码如下

public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        Savepoint savepoint1 =null;
        try {
            //1加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2获得链接
            String userName = "root";
            String passWord = "123456";
            String url = "jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT";
            connection = DriverManager.getConnection(url, userName, passWord);
            connection.setAutoCommit(false);//关闭自动提交事务
            //3定义sql,创建状态通道(进行sql语句的发送)
            statement = connection.createStatement();
            //4执行增删改查
            int result1 = statement.executeUpdate("insert into student values(10,'保存点1','3')");
            /*
            
            
            savepoint1 = connection.setSavepoint("Savepoint1");


			*/
            int result2 = statement.executeUpdate("insert into student values(11,'保存点2','3')");
            System.out.println(1/0);//通过异常让事务进行回滚,由于result1和result2属于同一个事务,因此都不执行
            connection.commit();//手动提交事务
            //返回结果为受影响的行数
            if(result1 > 0){
                System.out.println("执行成功");
            }else{
                System.out.println("执行失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            try {
				connection.rollback();
				/*
				
				
                connection.rollback(savepoint1);//回滚到保存点
                connection.commit();//提交事务,即保存点之前的事务
                
                
                */
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }finally {
            try {
                //5关闭资源
                if(statement != null){
                    statement.close();
                }
                if(connection != null){
                    connection.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }//end finally
    }//end main

保存点可以在事务中定义回滚点,如果发生异常,使用回滚方法来保存在保存点之前所做的更改即上述代码/**/注释部分

  • 在result1和result2之间定义回滚点savepoint1
savepoint1 = connection.setSavepoint("Savepoint1");
  • 异常处理的catch中设置回滚到保存点,并提交保存点之前的事务
	//connection.rollback();

    connection.rollback(savepoint1);//回滚到保存点
    connection.commit();//提交事务,即保存点之前的事务

此时运行时虽然会抛出异常,但是成功提交保存点之前的事务,即result1


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Selcouther

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值