JDBC中的事务机制

JDBC中事务机制:

1、JDBC中的事务是自动提交的,什么是自动提交?
只要执行任意一条DML语句,则自动提交一次。这是JDBC默认的事务行为。

但是在实际开发中,通常都是n条DML语句共同联合才能完成的,
必须保证这些DML语句同时执行成功或者同时失败。

//以下Test01程序是为了验证JDBC中事务的自动提交。

测试代码:

package jdbc.transaction;
import java.awt.image.DirectColorModel;
import java.sql.*;

public class Test01 {
    public static void main(String[] args) {

        // 先准备数据库连接配置信息
        String driver = "com.mysql.jdbc.Driver";
        String url = "jdbc:mysql://127.0.0.1:3306/study_test";
        String user = "root";
        String password = "666666";

        Connection conn = null;
        PreparedStatement ps = null;

        try {
            // 1、注册驱动
            Class.forName(driver);

            // 2、获取连接
            conn = DriverManager.getConnection(url, user, password);

            // 3、获取预编译的数据库操作对象
            // 4、执行sql语句

            // 假设某个事务需要执行一条insert和一条update语句,需要同时成功或者同时失败,事务才算完毕
            // 执行insert语句
            String sql1 = "insert into dept(deptno, dname, loc) values(?, ?, ?)";
            ps = conn.prepareStatement(sql1);
            // 给insert语句中的占位符传值
            ps.setInt(1, 50);
            ps.setString(2, "人事部");
            ps.setString(3, "北京");
            int line1 = ps.executeUpdate();
            System.out.println(line1 == 1 ? "插入成功" : "插入失败");

            // 执行update语句
            String sql2 = "update dept set loc = ? where deptno = ?";
            ps = conn.prepareStatement(sql2);
            // 给update语句中的占位符传值
            ps.setString(1, "天津");
            ps.setInt(2, 50);
            int line2 = ps.executeUpdate();
            System.out.println(line2 == 1 ? "更新成功" : "更新失败");

            // 验证事务的一致性:同时成功或者同时失败
            System.out.println(line1 == line2 ? "事务一致" : "事务不一致");

        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            if (ps != null) {
                try {
                    ps.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        } // try over

    } // main over
}

2、 JDBC演示银行转账事务:

先创建一个t_act账户表:

create table t_act (
	actno int(11),
	balance double(8,2) default 0.00,
	primary key (actno)
);

其中的double(8,2)表示8位有效数字,2位小数。
什么是有效数字?
从第一位不为0的数字开始算,例如:00123.45,有效数字为5位。

再插入2条信息:insert into t_act values(1001, 20000), (1002, 0);

重点3行代码(注意,是连接对象的三个方法,不是数据库操作对象):
conn.setAutoCommit(false); // 禁用自动提交事务
conn.commit(); // 手动提交事务
conn.rollback(); // 事务回滚

测试代码:

package jdbc.transaction;
import java.sql.*;

public class Test02 {
    public static void main(String[] args) {

        // 先准备数据库连接配置信息
        String driver = "com.mysql.jdbc.Driver";
        String url = "jdbc:mysql://127.0.0.1:3306/study_test";
        String user = "root";
        String password = "666666";

        Connection conn = null;
        PreparedStatement ps = null;

        try {
            // 1、注册驱动
            Class.forName(driver);

            // 2、获取连接
            conn = DriverManager.getConnection(url, user, password);
            // 获取连接后,立刻禁用事务的自动提交,相当于开启一个事务
            conn.setAutoCommit(false);

            // 3、获取预编译的数据库连接对象
            // 4、执行sql语句
            String sql = "update t_act set balance = balance + ? where actno = ?";
            ps = conn.prepareStatement(sql);

            // 第一次给占位符传值,1001账户余额减少1万元
            ps.setDouble(1, -10000);
            ps.setInt(2, 1001);
            int line = ps.executeUpdate();

            // 模拟中间出现异常,转账失败
            String s = null;
            //s.toString();

            // 第二次给占位符传值,1002账户余额增加1万元
            ps.setDouble(1, 10000);
            ps.setInt(2, 1002);
            line += ps.executeUpdate();

            // 程序执行到这里,说明以上代码没有出现异常
            // 处理事务结果,如果2个update语句都执行成功,则提交事务
            if (line == 2) {
                conn.commit();
                System.out.println("事务提交,转账成功!");
            }

        } catch (ClassNotFoundException | SQLException e) {
            // 出现异常,转账失败,事务回滚
            if (conn != null) {
                try {
                    conn.rollback();
                    System.out.println("事务回滚,转账失败!");
                } 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();
                }
            }
        } // try over

    } // main over
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值