【JDBC】学习路径7-转账-commit事务操作

Posted on 2022-05-25 14:35  罗芭Remoo  阅读(114)  评论(0编辑  收藏  举报

现在我们要做一个转账系统。

第一章:创建一张新的表格(用户银行账户表格)

在之前的JDBC_01数据库中新增一个表格,名字为:Account

  其中,有id、银行卡号、银行密码、账户余额。

 

创建表格代码:

create table account (id int not null auto_increment,username varchar(45),password varchar(45),money int,primary key(id));

 

 

创建好后,使用命令desc account;查看表格结构。

 

 

接下来,添加两个银行账户,那么就创建小猪和小牛两个人吧。

insert into account(username,password,money) values('小猪','123456',1000);

insert into account(username,password,money) values('小牛','654321',5000);

小猪有1000块钱,小牛有5000

好了,回到IDEA。

 

第二章:创建基本的转账功能

创建两个执行语句,一个是扣钱,一个是加钱。

public static boolean transform(String name1,String name2,int money){
    Connection con = null;
    PreparedStatement pstmt1 = null;
    PreparedStatement pstmt2 = null;
    ResultSet rs = null;
    try {
        con = JDBCUtils.getConnection();

        String sql = "update account set money = money-? where username = ?";
        pstmt1 = con.prepareStatement(sql);

        pstmt1.setInt(1, money);
        pstmt1.setString(2, name1);

        pstmt1.executeUpdate();//返回影响的行数


        sql = "update account set money = money+? where username = ?";
        pstmt2 = con.prepareStatement(sql);

        pstmt2.setInt(1, money);
        pstmt2.setString(2, name2);

        pstmt2.executeUpdate();//返回影响的行数
        
        
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        JDBCUtils.close(con, pstmt, rs);
    }
    return false;
}

 

转账代码在main中调用:

transform("小猪","小牛",100);

 

转账前:

转账后:

 

第三章:为什么要创建事务操作

在转账的过程中,有可能系统会发生错误,断电等等,

 

这样就有可能导致转钱的人的钱扣了,但是后面的代码就没有执行了,这样收款方就收不到钱了。

 

比如我们:

空指针错误(随便举的一个例子)

 

这样就导致小猪少了一百,但是小牛却没有进账。

 

第四章:使用事务功能Commit

事务操作,简单的说,

就是把一大堆需要一起执行的SQL语句打包好,再一起发送到数据库中。

这样就不会出现上面所说的,

前一条SQL语句发过去数据库了,但因为Java程序死机了,导致后面一个紧跟着的SQL语句没发过去。

 

使用方法:

在关键的代码(需要一起执行的SQL语句)前添加

con.setAutoCommit(false);

//关键代码,如转账

con.commit();

 

现在转账代码即:

public static boolean transform(String name1,String name2,int money){
    Connection con = null;
    PreparedStatement pstmt1 = null;
    PreparedStatement pstmt2 = null;
    ResultSet rs = null;
    try {
        con = JDBCUtils.getConnection();


        con.setAutoCommit(false);

        String sql = "update account set money = money-? where username = ?";
        pstmt1 = con.prepareStatement(sql);

        pstmt1.setInt(1, money);
        pstmt1.setString(2, name1);

        pstmt1.executeUpdate();//返回影响的行数

        //上面代码已经扣钱了
        //在这里发生了一些意外
        String a = null;
        a.charAt(2);
        //抛出空指针错误
        //下面代码就不执行了

        sql = "update account set money = money+? where username = ?";
        pstmt2 = con.prepareStatement(sql);

        pstmt2.setInt(1, money);
        pstmt2.setString(2, name2);

        pstmt2.executeUpdate();//返回影响的行数

        con.commit();

        return true;
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        JDBCUtils.close(con, pstmt1, rs);
    }
    return false;
}

 

 我们再执行转账。

 

即使程序依旧报出空指针错误,但是钱的问题不会发生了。