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)转账后:
在故意制造异常的情况下,转账虽然成功,但是双方的数据金额并未改变(在转账出现异常的情况下,转账事务被回滚):
但是,如果将异常去除,则转账可以正常进行: