ThreadLocal线程绑定的作用:能够在不同的层使用同一个线程对象。(主要用作:事务的Connection绑定,session对象的绑定)
eg:支付转账
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<title>转账页面</title>
</head>
<body>
<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="确定转账">
</form>
</body>
</html>
import java.sql.Connection;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class DateSourceUtils {
private static ComboPooledDataSource dataSource=new ComboPooledDataSource();
//创建ThreadLocal
static ThreadLocal<Connection> tl =new ThreadLocal<Connection>();
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
//获取当前线程上绑定的connection
public static Connection getCurrcentConnection() throws SQLException {
Connection conn=tl.get();
if (conn==null) {
//获取新的Connection
conn=getConnection();
//将conn绑定到ThreadLocal
tl.set(conn);
}
return conn;
}
//开启线程
public static void startTransaction() throws SQLException {
Connection conn=getCurrcentConnection();
conn.setAutoCommit(false);
}
//提交事务
public static void commitTransaction() throws SQLException {
Connection conn=getCurrcentConnection();
//将Connection从ThreadLocal中移除
conn.commit();
tl.remove();
conn.close();
}
//回滚事务
public static void rollbackTransaction() throws SQLException {
getCurrcentConnection().rollback();
}
}
package transfer.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import transfer.server.TransferServer;
/**
* Servlet implementation class TransferServlet
*/
@WebServlet("/transferservlet")
public class TransferServlet extends HttpServlet {
/**
* @see HttpServlet#HttpServlet()
*/
public TransferServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//获取参数
String out=request.getParameter("out");
String in=request.getParameter("in");
double money=Double.parseDouble(request.getParameter("money"));
//把参数传递给逻辑业务层
TransferServer server=new TransferServer();
boolean flag=server.Tranfer(out,in,money);
if (flag) {
response.getWriter().write("转账成功!");
}else {
response.getWriter().write("转账失败!");
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
import java.sql.Connection;
import java.sql.SQLException;
import transfer.dao.TransferDao;
import utils.DateSourceUtils;
import utils.DateSourceUtils.*;
public class TransferServer {
public Boolean Tranfer(String out, String in, double money) {
// TODO Auto-generated method stub
TransferDao dao=new TransferDao();
boolean flag=true;
//Connection conn=null;
try {
// //从数据库连接池取出一个connection
// conn=C3p0Utils.getConnection();
// //开启事务
// conn.setAutoCommit(false);
DateSourceUtils.startTransaction();
//转出钱
dao.out(out,money);
int i=1/0;
//转入钱
dao.in(in, money);
//conn.commit();
} catch (Exception e) {
flag=false;
//回滚事务
try {
//conn.rollback();
DateSourceUtils.rollbackTransaction();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
finally {
try {
//提交事务
//conn.commit();
DateSourceUtils.commitTransaction();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return flag;
}
}
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import utils.DateSourceUtils;
public class TransferDao {
public void out(String out, double money) throws SQLException {
QueryRunner runner=new QueryRunner();
Connection conn=DateSourceUtils.getCurrcentConnection();
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=DateSourceUtils.getCurrcentConnection();
String sql="update account set money=money+? where name=?";
runner.update(conn, sql, money,in);
}
}