本例的学生信息添加进入数据库的事务(可以提交事务,事务回滚,用本地线程完善)
主页面index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>学生信息管理 ?cmd=query'>查看学生信息
学生信息添加
工具包
获取数据库连接的工具ConnUtils5.java
package cn.hncu.utils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class ConnUtils5 {
//本地线程管理对象,用于实现: 同一个线程获取的连接是同一个
private static ThreadLocal< Connection> t=new ThreadLocal();
private final static List pool=new ArrayList();
private static int SIZE;//由资源文件读取
private ConnUtils5(){
}
static{
Properties p=new Properties();
try {
//下面这种方式在纯Java项目中可以读取到classpath下的资源文件,但无法读取JavaEE项目的。因为Tomcat把系统的默认类加载器改了
//p.load( ClassLoader.getSystemClassLoader().getSystemResourceAsStream("jdbc.properties"));
// p.load(ClassLoader.getSystemResourceAsStream("jdbc.properties"));
//读取Web项目的classpath下的资源文件,用这个可以
p.load(ConnUtils3.class.getClassLoader().getResourceAsStream("jdbc.properties"));
String driver=p.getProperty("driver");
String url=p.getProperty("url");
String name=p.getProperty("username");
String pwd=p.getProperty("password");
String ssize=p.getProperty("size");
SIZE=Integer.parseInt(ssize);
Class.forName(driver);
for(int i=0;i
代理
package cn.hncu.utils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
public class TxProxy implements InvocationHandler {
private Object srcObj=null;
private TxProxy(Object srcObj) {
this.srcObj = srcObj;
}
public static Object getProxy(Object srcObj){
System.out.println("srcObj:"+srcObj);
Object newObj=Proxy.newProxyInstance(
TxProxy.class.getClassLoader(),
srcObj.getClass().getInterfaces(),
new TxProxy(srcObj));
System.out.println("newObj:"+newObj);
return newObj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Connection con=null;
Object returnObj=null;
try {
con=ConnUtils5.getConnection();
System.out.println("invoke拿到一个链接:"+con);
con.setAutoCommit(false);
returnObj=method.invoke(srcObj, args);
System.out.println("提交一个事务...");
con.commit();
} catch (Exception e) {
try {
System.out.println("回滚一个事务...");
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
try {
con.setAutoCommit(true);
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return returnObj;
}
}
代理2:不需要强转,但是代理了所有
package cn.hncu.utils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
public class TxProxy2 implements InvocationHandler {
private Object srcObj=null;
private TxProxy2(Object srcObj) {
this.srcObj = srcObj;
}
public static T getProxy(Class c){
Object obj=null;
try {
obj = c.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
Object newObj=Proxy.newProxyInstance(
TxProxy2.class.getClassLoader(),
c.getInterfaces(),
new TxProxy2(obj));
return (T) newObj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Connection con=null;
Object returnObj=null;
try {
con=ConnUtils5.getConnection();
System.out.println("invoke拿到一个链接:"+con);
con.setAutoCommit(false);
returnObj=method.invoke(srcObj, args);
System.out.println("提交一个事务...");
con.commit();
} catch (Exception e) {
try {
System.out.println("回滚一个事务...");
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
try {
con.setAutoCommit(true);
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return returnObj;
}
}
注解
package cn.hncu.utils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value=ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Transaction {
}
代理3:用注解实现需要事务则用事务
package cn.hncu.utils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
public class TxProxy3 implements InvocationHandler {
private Object srcObj=null;
private TxProxy3(Object srcObj) {
this.srcObj = srcObj;
}
public static T getProxy(T srcObj){
Object newObj=Proxy.newProxyInstance(
TxProxy3.class.getClassLoader(),
srcObj.getClass().getInterfaces(),
new TxProxy3(srcObj));
return (T) newObj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(method.isAnnotationPresent(Transaction.class)){
Connection con=null;
Object returnObj=null;
try {
con=ConnUtils5.getConnection();
System.out.println("invoke拿到一个链接:"+con);
con.setAutoCommit(false);
//真正的业务代码,放行
returnObj=method.invoke(srcObj, args);
System.out.println("提交一个事务...");
con.commit();
} catch (Exception e) {
try {
System.out.println("回滚一个事务...");
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
try {
con.setAutoCommit(true);
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return returnObj;
}else{
System.out.println("不存在事务注解,直接放行!");
return method.invoke(srcObj, args);
}
}
}
资源文件jdbc.properties
##MySQL
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8
username=root
password=1234
size=3
##Oracle
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
#username=scott
#password=tiger
stud层的servlet层–QueryServlet.java
package cn.hncu.stud.servlet;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.hncu.domain.Book;
import cn.hncu.domain.Stud;
import cn.hncu.stud.service.IStudService;
import cn.hncu.stud.service.StudServiceImpl;
import cn.hncu.utils.TxProxy3;
public class QueryServlet extends HttpServlet {
//注入
//1.
// IStudService service=(IStudService) TxProxy.getProxy(new StudServiceImpl());
//2.
// IStudService service=TxProxy2.getProxy(StudServiceImpl.class);
//3.
IStudService service=TxProxy3.getProxy(new StudServiceImpl());
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String cmd=request.getParameter("cmd");
System.out.println("cmd:"+cmd);
if("query".equals(cmd)){
query(request, response);
}else if("add".equals(cmd)){
add(request, response);
}
}
public void query(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("service:"+service);
List 


