转账示意图
在service层使用threadLocal示意图
1.页面显示
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 动态获取应用名称 -->
<form action="${pageContext.request.contextPath }/transfer" method="post">
转出账户:<input type="text" name="out"><br>
转入账户:<input type="text" name="in"><br>
转账金额:<input type="text" name="money"><br>
<input type="submit" value="确认转账">
</form>
</body>
</html>
2.自定义的工具类
package com.xiaowei.utils;
import java.sql.Connection;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class MyDatasourceUtils {
// 1.加载c3p0配置文件 获得缓存池
public static ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 2.获取connection连接对象
public static Connection getConnection() throws SQLException{
return dataSource.getConnection();
}
// 3.创建threadLocal
public static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
// 4.获取当前线程上绑定的conn
public static Connection getCurrentConnection() throws SQLException{
// 从threadLocal寻找 当前线程是否有对象的connection
Connection conn = tl.get();
if (conn==null) {
conn = getConnection();
// 然后将conn绑定到当前的threadLocal(map)上
tl.set(conn);
}
return conn;
}
// 5.开启事物
public static void startTransaction() throws SQLException{
Connection conn = getCurrentConnection();
conn.setAutoCommit(false);
}
// 6.回滚事物
public static void rollback() throws SQLException{
getCurrentConnection().rollback();
}
// 7.提交事物
public static void commint() throws SQLException{
Connection conn = getCurrentConnection();
conn.commit();
// 将connection从threadLocal中移除
tl.remove();
conn.close();
}
}
3.web层
package com.xiaowei.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.xiaowei.transfer.service.transferService;
public class TransferServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.获取转出账户 转入账户 金额
String out = request.getParameter("out");
String in = request.getParameter("in");
String moneyNum = request.getParameter("money");
// 2.调用service层的转账方法 将这些参数传递到service层
transferService tran = new transferService();
tran.transfer(out,in,moneyNum);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
4.service层
package com.xiaowei.transfer.service;
import java.sql.SQLException;
import com.xiaowei.transfer.dao.TransferDao;
import com.xiaowei.utils.MyDatasourceUtils;
public class transferService {
public void transfer(String out, String in, String moneyNum) {
TransferDao dao = new TransferDao();
// 执行转出操作
try {
// 开启事物
MyDatasourceUtils.startTransaction();
// 转出操作
dao.out(out, moneyNum);
// 转入操作
dao.in(in, moneyNum);
} catch (SQLException e) {
try {
// 回滚
MyDatasourceUtils.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
try {
// 提交
MyDatasourceUtils.commint();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
5.dao层
package com.xiaowei.transfer.dao;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import com.xiaowei.utils.MyDatasourceUtils;
public class TransferDao {
// 转出操作
public void out(String out,String money) throws SQLException{
QueryRunner runner = new QueryRunner();
// 这里需要获取conn连接对象 先使用以前的
Connection conn = MyDatasourceUtils.getCurrentConnection();
String sql = "update count set money=money-? where name=?";
runner.update(conn, sql, money,out);
}
// 转入操作
public void in(String in,String money) throws SQLException{
QueryRunner runner = new QueryRunner();
// 这里需要获取conn连接对象 先使用以前的
Connection conn = MyDatasourceUtils.getCurrentConnection();
String sql = "update count set money=money+? where name=?";
runner.update(conn, sql, money,in);
}
}