编写框架实现事务控制和分层进行解耦
TransactionManager
public class TransactionManager{
private TransactionManager(){}
private static DataSource source = new ComboPoolDataSource();
private static ThreadLocal<Boolean> isTran_Local = new ThreadLocal<Boolean>(){
@Override
protected Boolean initalValue(){
return false;
}
}
//保存真实连接的代理连接对象
private static ThreadLocal<Connection> proxyConn_local = new ThreadLocal<Connection>();
//保存真实的连接对象
private static ThreadLocal<Connection> realConn_local = new ThreadLocal<Conntion>();
//开启事务的方法
public static void startTran()throws SQLException{
isTran_Local.set(true);
final Connection conn = source.getConnection();//从连接池中获取连接对象
conn.setAutoCommit(false);//开启事务
realConn_local.set(conn);//为了方便关闭连接,将真实连接对象保存在当前线程中
//由于一个事务需要执行多条SQL语句,每个数据库执行完会自动调用关闭连接,这样后面的SQL语句后续无法执行,所以这个地方的方法改造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())){
return null;
}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());
}
//如何开启事务则返回改造后的Connection(getConnection)如果没有开启事务则返回普通数据源
public static DataSource getSource()throw 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){
if("getConnection".equals(method.getName())){
return proxyConn_Local.get();
}
}
});
}else{
return source;
}
}
public static void release(){
DbUtils.closeQuietly(realConn_local.get());
realConn_local.remove();
proxyConn_local.remove();
isTran_local.remove();
}
}
分离事务控制的工厂类
public Class BasicFactory{
private static BasicFactory factory = new BasicFactory();
priavte static Properties properties = null;
private BasicFactory(){}
static{
try{
properties = new Properties();
properties.load(new FileReader(BasicFactory.class.getClassLoader().getResource("config.properties").getPath()));
}catch(Exception e){
throw new RuntimeException(e);
}
}
public static BasicFactory getInstace(){
return factory;
}
//获取Service的方法
public <T> T getService(Class<T> clazz){
try{
String interfaceName = clazz.getSimpleName();
String implName = properties.getProperty(interfaceName);
final T service = (T)Class.forName(implName).newInstance();
//实现AOP,生产Service代理,根据注解确定执行Service里面方法前后的操作
try{
TransactionManager.start();
Object object = method.invoke(service,args);
TransactionManager.commit();
return obj;
}catch(Exception e){
TransactonManager.rollback();
throw new RuntimeException(e);
}finally{
TransactionManager.release();//释放资源
}
}else{
return method.invoke(service,args);
}
});
return proxyService;
}catch(Exception e){
throw new RuntimeException(e);
}
}
//获取Dao的方法
public <T> T getDao(Class<T> clazz){
try{
String interfaceName = clazz.getSimpleName();
String implName = properties.getProperty(interfaceName);
return (T)Class.forName(implName).newInstance();
}catch(Exception e){
throw new RuntimException(e);
}
}
}
TransactionManager
public class TransactionManager{
private TransactionManager(){}
private static DataSource source = new ComboPoolDataSource();
private static ThreadLocal<Boolean> isTran_Local = new ThreadLocal<Boolean>(){
@Override
protected Boolean initalValue(){
return false;
}
}
//保存真实连接的代理连接对象
private static ThreadLocal<Connection> proxyConn_local = new ThreadLocal<Connection>();
//保存真实的连接对象
private static ThreadLocal<Connection> realConn_local = new ThreadLocal<Conntion>();
//开启事务的方法
public static void startTran()throws SQLException{
isTran_Local.set(true);
final Connection conn = source.getConnection();//从连接池中获取连接对象
conn.setAutoCommit(false);//开启事务
realConn_local.set(conn);//为了方便关闭连接,将真实连接对象保存在当前线程中
//由于一个事务需要执行多条SQL语句,每个数据库执行完会自动调用关闭连接,这样后面的SQL语句后续无法执行,所以这个地方的方法改造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())){
return null;
}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());
}
//如何开启事务则返回改造后的Connection(getConnection)如果没有开启事务则返回普通数据源
public static DataSource getSource()throw 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){
if("getConnection".equals(method.getName())){
return proxyConn_Local.get();
}
}
});
}else{
return source;
}
}
public static void release(){
DbUtils.closeQuietly(realConn_local.get());
realConn_local.remove();
proxyConn_local.remove();
isTran_local.remove();
}
}
分离事务控制的工厂类
public Class BasicFactory{
private static BasicFactory factory = new BasicFactory();
priavte static Properties properties = null;
private BasicFactory(){}
static{
try{
properties = new Properties();
properties.load(new FileReader(BasicFactory.class.getClassLoader().getResource("config.properties").getPath()));
}catch(Exception e){
throw new RuntimeException(e);
}
}
public static BasicFactory getInstace(){
return factory;
}
//获取Service的方法
public <T> T getService(Class<T> clazz){
try{
String interfaceName = clazz.getSimpleName();
String implName = properties.getProperty(interfaceName);
final T service = (T)Class.forName(implName).newInstance();
//实现AOP,生产Service代理,根据注解确定执行Service里面方法前后的操作
T proxyService = (T)Proxy.newProxyInstance(service.getClass().getClassLoader(),service.getClass().getInterfaces(),new InvocationHandler(){
Method m = service.getClass().getMethod(method.getName(),method.getParamterTypes());
if(m.isAnnotationPresent(Tran.class)){//如果有注解则进行手动事务控制try{
TransactionManager.start();
Object object = method.invoke(service,args);
TransactionManager.commit();
return obj;
}catch(Exception e){
TransactonManager.rollback();
throw new RuntimeException(e);
}finally{
TransactionManager.release();//释放资源
}
}else{
return method.invoke(service,args);
}
});
return proxyService;
}catch(Exception e){
throw new RuntimeException(e);
}
}
//获取Dao的方法
public <T> T getDao(Class<T> clazz){
try{
String interfaceName = clazz.getSimpleName();
String implName = properties.getProperty(interfaceName);
return (T)Class.forName(implName).newInstance();
}catch(Exception e){
throw new RuntimException(e);
}
}
}