在进行转账操作时,我们要保证数据的统一性。(例如,当一个账户转出金额过程中,如果出现系统错误或者说是停电断网等特殊情况,将会发生转出账户减少,转入账户金额未添加的情况。)因此,我们需要通过事务控制:
注意点:在事务控制语句代码中,要保证Connection是同一个
目录结构:
web层servlet客户端交互代码:
package com.zys.transfer.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zys.transfer.service.TransferService;
public class TransferServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//接收转账的参数,传递给service层
String out = request.getParameter("out");
String in = request.getParameter("in");
String moneyStr = request.getParameter("money");
double money = Double.parseDouble(moneyStr);//强制转化成double类型
//调用业务层的转账方法
TransferService service = new TransferService();
Boolean TransferIsSuccess = service.transfer(out,in,money);
if(TransferIsSuccess){
response.getWriter().write("转账成功");
}else{
response.getWriter().write("转账失败");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
service层业务逻辑处理代码:
package com.zys.transfer.service;
import java.sql.Connection;
import java.sql.SQLException;
import com.zys.transfer.dao.TransferDao;
import com.zys.utils.DataSourceUtils;
public class TransferService {
public Boolean transfer(String out, String in, double money) {
TransferDao dao = new TransferDao();
Boolean TransferIsSuccess = true;
Connection conn = null;
try {
//开启事务
conn = DataSourceUtils.getConnection();
conn.setAutoCommit(false);
//转出钱的方法
dao.out(conn,out,money);
//转入钱的方法
dao.in(conn,in,money);
} catch (Exception e) {
TransferIsSuccess = false;
//回滚事务
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}finally{
try {
conn.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return TransferIsSuccess;
}
}
dao层数据库交互代码:
package com.zys.transfer.dao;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import com.zys.utils.DataSourceUtils;
public class TransferDao {
public void out(Connection conn,String out, double money) throws SQLException {
QueryRunner runner = new QueryRunner();
//Connection conn = DataSourceUtils.getConnection();
String sql = "update account set money=money-? where name=?";
runner.update(conn, sql, money,out);
}
public void in(Connection conn,String in, double money) throws SQLException {
QueryRunner runner = new QueryRunner();
//Connection conn = DataSourceUtils.getConnection();
String sql = "update account set money=money+? where name=?";
runner.update(conn, sql, money,in);
}
}
通过TheadLocal对象获取Connection方式实现:
因为service层是处理业务逻辑的,dao层是处理数据库的,conn不应该在service层出现,用此种方式可以实现,而保证在一个访问中三层架构Connection为同一个。
service层业务逻辑处理代码:
package com.zys.transfer.service;
import java.sql.Connection;
import java.sql.SQLException;
import com.zys.transfer.dao.TransferDao;
import com.zys.utils.DataSourceUtils;
public class TransferService {
public Boolean transfer(String out, String in, double money) {
TransferDao dao = new TransferDao();
Boolean TransferIsSuccess = true;
Connection conn = null;
try {
//使用TheaadLocal存储Connection
//开启事务
//conn = DataSourceUtils.getConnection();
//conn.setAutoCommit(false);
DataSourceUtils.startTransaction();
//转出钱的方法
dao.out(out,money);
//转入钱的方法
dao.in(in,money);
} catch (Exception e) {
TransferIsSuccess = false;
//回滚事务
try {
//conn.rollback();
DataSourceUtils.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}finally{
//提交事务
try {
//conn.commit();
DataSourceUtils.commitAndRelease();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return TransferIsSuccess;
}
}
dao层数据库交互代码:
package com.zys.transfer.dao;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import com.zys.utils.DataSourceUtils;
public class TransferDao {
public void out(String out, double money) throws SQLException {
QueryRunner runner = new QueryRunner();
Connection conn = DataSourceUtils.getCurrentConnection();
String sql = "update account set money=money-? where name=?";
runner.update(conn, sql, money,out);
}
public void in(String in, double money) throws SQLException {
QueryRunner runner = new QueryRunner();
Connection conn = DataSourceUtils.getCurrentConnection();
String sql = "update account set money=money+? where name=?";
runner.update(conn, sql, money,in);
}
}