您的位置:首页 > 编程语言 > Java开发

java中的事务管理

2016-04-03 20:04 531 查看
package myweb.book.utils;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.sql.Connection;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.commons.dbutils.DbUtils;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class TransactionManager {

private TransactionManager() {

}

private static DataSource source = new ComboPooledDataSource();

private static ThreadLocal<Boolean> isTran_local = new ThreadLocal<Boolean>(){

@Override

protected Boolean initialValue() {//设置是否开启事务

return false;//--默认不开启事务控制

}

};

//--用它来存改造后的链接

private static ThreadLocal<Connection> proxyConn_local = new ThreadLocal<Connection>(){};

//--用它来存放真正的链接

private static ThreadLocal<Connection> realconn_local = new ThreadLocal<Connection>(){};

/**

* 开启事务控制

* @throws SQLException

*/

public static void startTran() throws SQLException{

isTran_local.set(true);//--将开启事务标记改为true

final Connection conn = source.getConnection();//获取链接对象

conn.setAutoCommit(false);//--将自动开启事务关闭

realconn_local.set(conn);//--Ϊ保存真正的链接对象

//-由于我想是一个链接可以用与多个对数据库操作,而每次操作后都会有隐式的关闭链接操作(close)所以用改造close

Connection proxyConn = (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces()

, new InvocationHandler(){

public Object invoke(Object proxy, Method method,

Object[] args) throws Throwable {

if("close".equals(method.getName())){//如果方法为close

return null;//将close操作不进行任何真正操作

}else{

return method.invoke(conn, args);//其他方法原样调用

}

}

});

proxyConn_local.set(proxyConn);//将改造的链接对象放存到对应的地方

}

/**

* 提交事务

*/

public static void commit(){

DbUtils.commitAndCloseQuietly(proxyConn_local.get());

}

/**

* 回滚事务

*/

public static void rollback(){

DbUtils.rollbackAndCloseQuietly(proxyConn_local.get());

}

/**

* 对于要开启事务的返回的链接都要是同一个,这就需要改造getConnection()的方法

* 对于不需开启事务就直接返回原连方法

* @return

* @throws SQLException

*/

public static DataSource getSource() throws SQLException{

if(isTran_local.get()){//--是否需要开启事务

return (DataSource) Proxy.newProxyInstance(source.getClass().getClassLoader(), source.getClass().getInterfaces()

,new InvocationHandler(){

public Object invoke(Object proxy, Method method,

Object[] args) throws Throwable {

if("getConnection".equals(method.getName())){//如果方法是各同Connetion()则需要改造

return proxyConn_local.get();//返回存在本地线程池中的链接对象

}else{

return method.invoke(source, args);//其他方法直接返回

}

}

});

}else{//-对不需要开启事务的直接返回source

return source;

}

}

/**

* 释放资源

*/

public static void release(){

DbUtils.closeQuietly(realconn_local.get());//关闭链接֮

realconn_local.remove();

proxyConn_local.remove();

isTran_local.remove();

}

}

package myweb.book.factor;

import java.io.FileReader;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.Properties;

import myweb.book.annotion.Tran;

import myweb.book.dao.Dao;

import myweb.book.service.Service;

import myweb.book.utils.TransactionManager;

public class BasicFactory {

private static BasicFactory factory = new BasicFactory();

private static Properties prop = null;

private BasicFactory(){}

static{

try {

prop = new Properties();

prop.load(new FileReader(BasicFactory.class.getClassLoader().getResource("config.properties").getPath()));

} catch (Exception e) {

e.printStackTrace();

throw new RuntimeException(e);

}

}

public static BasicFactory getFactory(){

return factory;

}

@SuppressWarnings("unchecked")

/**

* 生成service对象

*/

public <T extends Service> T getService(Class<T> clazz){

try{

//利用反射获取service对象

String infName = clazz.getSimpleName();

String implName = prop.getProperty(infName);

final T service = (T) Class.forName(implName).newInstance();

//动态改造service对象使其可以实现对事务的控制

T proxyService = (T) Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces()

, new InvocationHandler(){

//改造service对象中的方法

public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {

if(method.isAnnotationPresent(Tran.class)){//判断service对象中的方法是否需要开启事务控制(是)

try{

TransactionManager.startTran();//开启一个事务

Object obj = method.invoke(service, args);//调用原有方法

TransactionManager.commit();//提交事务

return obj;

}catch (InvocationTargetException e) {

TransactionManager.rollback();//--回滚事务

throw new RuntimeException(e.getTargetException());

} catch (Exception e) {

TransactionManager.rollback();//--回滚事务

throw new RuntimeException(e);

}finally{

TransactionManager.release();//--释放资源

}

}else{//不需要开启事务直接返回原方法

return method.invoke(service, args);

}

}

});

return proxyService;

}catch (Exception e) {

e.printStackTrace();

throw new RuntimeException(e);

}

}

/**

* 生成dao对象

*/

public <T extends Dao> T getDao(Class<T> clazz){

try{

String infName = clazz.getSimpleName();

String implName = prop.getProperty(infName);

return (T) Class.forName(implName).newInstance();

}catch (Exception e) {

e.printStackTrace();

throw new RuntimeException(e);

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: