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