JDBC_05事务相关

JDBC_05事务相关

1.演示jdbc事务自动提交机制

1.1建表并插入数据

drop table if exists t_vip;
create table t_vip(
     id int primary key auto_increment,
     name varchar(255)
);
insert into t_vip(name) values('zhangsan');
insert into t_vip(name) values('lisi');
commit;

查看数据:

1.2编写程序同时修改两条记录

在两条sql语句之间加一个空指针异常,使程序执行第一条sql语句后,终止运行。

package com.tsccg.jdbc.transaction;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * @Author: TSCCG
 * @Date: 2021/07/28 19:19
 * 演示jdbc的事务自动提交机制
 */
public class TransactionDemo01 {
    //程序执行入口
    public static void main(String[] args) {
        boolean result = change();
        System.out.println(result ? "操作成功" : "操作失败");
    }
    /**
     * 修改t_vip表的数据
     * @return 返回执行结果
     */
    private static boolean change() {
        boolean isSuccess = false;
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            //1.注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接
            String url = "jdbc:mysql://localhost:3306/tsccg";
            String user = "root";
            String password = "123456";
            conn = DriverManager.getConnection(url,user,password);
            
            //3.获取预编译数据库操作对象
            String sql = "update t_vip set name = ? where id = ?";
            ps = conn.prepareStatement(sql);
            //第一次给占位符赋值
            ps.setString(1,"张三");
            ps.setInt(2,1);
            //4.1执行sql语句
            int count = ps.executeUpdate();

            //设置一个空指针异常
            String str = null;
            str.toString();

            //第二次给占位符赋值
            ps.setString(1,"李四");
            ps.setInt(2,2);
            //4.2执行sql语句
            count += ps.executeUpdate();

            //如果两次执行sql语句都成功了,那么count的值就会是2
            if (count == 2) {
                isSuccess = true;
            }
        } catch (SQLException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            //6.释放资源
            if (ps != null) {
                try {
                    ps.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
        return isSuccess;
    }
}

1.3查看运行结果

Exception in thread "main" java.lang.NullPointerException
	at com.tsccg.jdbc.transaction.TransactionDemo01.change(TransactionDemo01.java:53)
	at com.tsccg.jdbc.transaction.TransactionDemo01.main(TransactionDemo01.java:23)

由图知,在执行过第一条sql语句后,就立即将其提交了。

从该案例中,可见jdbc会自动提交事务。

在开发中,会有很多操作要求同时成功或同时失败,这样的自动提交机制是不可行的。

比如说银行转账操作。A账户中有20000元,B账户中有0元。

A向B转账10000元,这就设计到两个修改操作:

  1. A账户减去10000元,
  2. B账户增加10000元。

如果使用自动提交机制,在A账户中减去金额后就会自动提交一次事务,无论之后的程序如何运行。

假设在转账过程中遇到了如上面程序中的异常,就会导致在A账户减去金额后,B账户没有增加金额。

所以为了数据安全,要把两步修改操作放进一个事务中,要成功一起成功,要失败一起失败。

2.设置事务手动提交和关闭

重点有三条代码:

//conn数据库连接对象
conn.setAutoCommit(false);//关闭自动提交
conn.commit();//手动提交
conn.rollback();//回滚。

2.1修改上面的程序

现用这三条代码修改上面的程序

package com.tsccg.jdbc.transaction;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * @Author: TSCCG
 * @Date: 2021/07/28 22:24
 */
public class TransactionDemo02 {
    public static void main(String[] args) {
        boolean result = change();
        System.out.println(result ? "操作成功" : "操作失败");
    }
    /**
     * 修改t_vip表的数据
     * @return 返回执行结果
     */
    private static boolean change() {
        boolean isSuccess = false;
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            //1.注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接
            String url = "jdbc:mysql://localhost:3306/tsccg";
            String user = "root";
            String password = "123456";
            conn = DriverManager.getConnection(url,user,password);

            //关闭自动提交
            conn.setAutoCommit(false);

            //3.获取预编译数据库操作对象
            String sql = "update t_vip set name = ? where id = ?";
            ps = conn.prepareStatement(sql);
            //第一次给占位符赋值
            ps.setString(1,"张三");
            ps.setInt(2,1);
            //4.1执行sql语句
            int count = ps.executeUpdate();

            //设置一个空指针异常
            String str = null;
            str.toString();

            //第二次给占位符赋值
            ps.setString(1,"李四");
            ps.setInt(2,2);
            //4.2执行sql语句
            count += ps.executeUpdate();

            //如果两次执行sql语句都成功了,那么count的值就会是2
            if (count == 2) {
                isSuccess = true;
            }
            //手动提交事务
            conn.commit();
        } catch (SQLException | ClassNotFoundException e) {
            //回滚事务
            if(conn != null) {
                try {
                    conn.rollback();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            e.printStackTrace();
        } finally {
            //6.释放资源
            if (ps != null) {
                try {
                    ps.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
        return isSuccess;
    }
}

重新初始化表中数据:

2.2重新运行程序

Exception in thread "main" java.lang.NullPointerException
	at com.tsccg.jdbc.transaction.TransactionDemo02.change(TransactionDemo02.java:48)
	at com.tsccg.jdbc.transaction.TransactionDemo02.main(TransactionDemo02.java:14)

可见,即使已经执行了第一条sql语句,当程序遇到异常后,也会将执行的语句进行回滚,表中数据并未受影响。

去除空指针异常再次运行:

操作成功

两条语句同时执行成功。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

TSCCG

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

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

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

打赏作者

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

抵扣说明:

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

余额充值