代理模式增强版

package cn.hncu.pool;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;

public class ConnUtils3 {
private static List<Connection> pool = new ArrayList<Connection>();
private static final int NUM=3;
static{
Properties p = new Properties();
try {
p.load(ClassLoader.getSystemResourceAsStream("jdbc.properties"));
String driver = p.getProperty("driver");
String url = p.getProperty("url");
String name = p.getProperty("username");
String pwd = p.getProperty("password");
Class.forName(driver);

for (int i = 0; i < NUM; i++) {
final Connection conn = DriverManager.getConnection(url, name, pwd);
//用代理模式生成一个增强版的conn对象,把它的close()方法拦截更改掉
Object newObj = Proxy.newProxyInstance(
ConnUtils3.class.getClassLoader(),
new Class[]{Connection.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(method.getName().equals("close")){
pool.add((Connection)proxy);
return null;
}
return method.invoke(conn, args);
}
});

pool.add((Connection)newObj);
}
} catch (Exception e) {
e.printStackTrace();
}
}

public static synchronized Connection getConn() {
if(pool.size()<=0){
System.out.println("池中没有连接了....");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return getConn();
}
return pool.remove(0);
}

}

-------------------------------------------------------------------------------------------------

package cn.hncu.tx;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import cn.hncu.pool.ConnUtils3;

//※※使用的是多例的连接池ConnUtils2 ---更改过con.close()方法的版本

public class TxDemo4 {

public static void main(String[] args) throws Exception {
Connection con = ConnUtils3.getConn();
System.out.println("main线程获得一个连接:"+con);
Statement st = con.createStatement();
try {
con.setAutoCommit(false);//SQL: START TRANSACTION; //开启事务
st.execute("INSERT INTO person2 VALUES('P200','赵子龙','1')");

new MyThread4(1).start();
new MyThread4(2).start();
new MyThread4(3).start();
new MyThread4(4).start();
new MyThread4(5).start();

Thread.sleep(1000);

con.commit();
System.out.println("main线程提交一个事务....");
} catch (Exception e) {
con.rollback();
System.out.println("main线程回滚一个事务.....");
}finally{
con.setAutoCommit(true);
con.close(); //※※※※
}
}

}

class MyThread4 extends Thread{
private int num;
public MyThread4(int num){
this.num = num;
}
@Override
public void run() {
Connection con = ConnUtils3.getConn();
System.out.println(num+"线程获得一个连接:"+con);
try {
Statement st = con.createStatement();
con.setAutoCommit(false);//SQL: START TRANSACTION; //开启事务
String sql = "INSERT INTO person2 VALUES('P09"+num+"','赵子龙','1')";

if(num==3){
sql = "INSERT INTO person2 VALUES('P09"+num+",'赵子龙','1')";
}else{
Thread.sleep(100);
}
st.execute(sql);
con.commit();
System.out.println(num+"线程提交一个事务....");
} catch (Exception e) {
try {
con.rollback();
System.out.println(num+"线程回滚一个事务.....");
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
try {
con.setAutoCommit(true);
con.close();//※※※※
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

 

posted @ 2016-11-09 23:17  折腾青春  阅读(173)  评论(0编辑  收藏  举报