事务——银行转账

Posted zhai1997

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事务——银行转账相关的知识,希望对你有一定的参考价值。

1、如果不添加对事务的管理,转账过程中可能会出现数据的不一致现象,造成转账时的数据出错,通过添加对事务的管理,在出现意外终止转账的时候,可以选择不对数据库的修改进行提交,并对事务进行回滚操作。

2、核心代码:

(1)jsp:

transfer.jsp:

<body bgcolor="#00ffff">
<form action="${pageContext.request.contextPath}/transferservlet" method="post">
    转出账户:<input type="text" name="out"><br>
    转入账户:<input type="text" name="in"><br>
    转账金额:<input type="text" name="money"><br>
    <input type="submit" value="确认转账"><br>
</form>
</body>
</html>

通过jsp收集用户的信息:转账人账户名、收账人账户名、转账金额。将这些数据提供给web层的Servlet。

(2)web层:

servlet:

protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        String inName=request.getParameter("in");//从表单获得的数据都为字符串类型
        String outName=request.getParameter("out");
        String stringmoney=request.getParameter("money");
        double money=Double.parseDouble(stringmoney);//字符串类型的money变为double
        TransferService transferService=new TransferService();
        boolean result=transferService.transfer(outName,inName,money);
        if(result){
            response.getWriter().write("成功");
        }else{
            response.getWriter().write("失败");
        }
    }

将从jsp获得的数据作为参数调用service层的方法。

(3)service层:

public class TransferService {
    public boolean transfer(String outName,String inName,double money) {
        boolean result=true;
        Connection con=null;
        try {
            con=C3p0Utils.getConnection();//在service层创建con对象,保证了dao层操作的是同一个对象
            con.setAutoCommit(false);
            TransferDao dao = new TransferDao();
            dao.out(con,outName, money);//将同一个con对象以参数的形式传递到dao层
            int num=8/0;//故意制造异常,使得转账过程意外终止
            dao.in(con,inName, money);
        }catch (Exception e){
            result=false;
            try {
                if (con!= null) {
                   con.rollback();
                }
            }catch (Exception e1){
                e1.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            try{
                con.commit();
            }catch (SQLException e2){
                e2.printStackTrace();
            }
        }
        return true;
    }

接收Servlet的数据,作为参数执行dao层的函数,并故意制造异常,使得转账过程意外终止,转账过程回滚,如果无异常则正常提交。将connection对象放在service层,保证了转入转出的操作调用的是同一个connection对象。

(4)dao层:

public class TransferDao {
    public void out(Connection con,String outName, double money) {
        try {
            QueryRunner qr = new QueryRunner();
            String sql = "UPDATE transfer SET money=money-? WHERE username=? ";
            Object[] update = {money, outName};
            qr.update(con, sql, update);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public void in(Connection con,String inName, double money) {
        try {
            QueryRunner qr = new QueryRunner();
            String sql = "UPDATE transfer SET money=money+? WHERE username=? ";
            Object[] update = {money, inName};
            qr.update(con, sql, update);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

通过C3P0和数据库工具类操作数据库,完成对数据库的账户的增减。

3、过程演示:

(1)转账前:

技术图片

 

 技术图片

 

 (2)转账后:

在故意制造异常的情况下,转账虽然成功,但是双方的数据金额并未改变(在转账出现异常的情况下,转账事务被回滚):

技术图片

 

 但是,如果将异常去除,则转账可以正常进行:

技术图片

 

 技术图片

 

 技术图片

 

以上是关于事务——银行转账的主要内容,如果未能解决你的问题,请参考以下文章

Java总结(随笔)——代码总结JDBC以及事务,以银行转账,查账等为例

Spring事务管理的四种方式(以银行转账为例)

Spring事务管理的四种方式(以银行转账为例)

Spring事务银行转账示例

从银行转账失败到分布式事务:总结与思考

事务管理模型(银行转账)