上一篇博客总结了动态代理的使用及代码的含义。接下来,继续探究动态代理的实地应用——利用动态代理来封装事务。
首先,要先来回忆一下最原始的封装好的事务的代码,这里在连接数据库时用到了TheadLocal这个类,通过它可以来保证在执行业务逻辑过程中来
保证每一次使用的connection的连接对象都执行的是同一个线程内的connection。
事务的封装
/**
* 采用ThreadLocal封装Connection
* @author yanyan
*
*/
public class ConnectionManager {
private static ThreadLocal<Connection> connectionHolder=new ThreadLocal<Connection>();
public static Connection getConnection(){
Connection conn=connectionHolder.get();
if(conn==null){
try{
JdbcConfig jdbcConfig=XmlConfigReader.getInstance().getJdbcConfig();
Class.forName(jdbcConfig.getDriverName());
conn=DriverManager.getConnection(jdbcConfig.getUrl(),jdbcConfig.getUserName(),jdbcConfig.getPassword());
connectionHolder.set(conn);
}catch (Exception e) {
throw new ApplicationException("系统错误,请联系管理员!");
}
}
return conn;
}
public static void closeConnection(){
Connection conn=connectionHolder.get();
if(conn!=null){
try{
conn.close();
connectionHolder.remove();
}catch(SQLException e){
e.printStackTrace();
}
}
}
/**
* 手动提交事务
* @param conn
*/
public static void beginTransaction(Connection conn){
try{
if(conn !=null){
if(conn.getAutoCommit()){
conn.setAutoCommit(false);
}
}
}catch(SQLException e){}
}
/**
*
* 提交事务
* @param conn
*/
public static void commitTransaction(Connection conn){
try{
if(conn !=null){
if(!conn.getAutoCommit()){
conn.commit();
}
}
}catch(SQLException e){}
}
/**
* 回滚事务
* @param conn
*/
public static void rollbackTransaction(Connection conn){
try{
if(conn!=null){
if(!conn.getAutoCommit()){
conn.rollback();
}
}
}catch(SQLException e){}
}
/**
* 重置connection状态
* @param conn
*/
public static void resetConnection(Connection conn){
try{
if(conn!=null){
if(conn.getAutoCommit()){
conn.setAutoCommit(false);
}else{
conn.setAutoCommit(true);
}
}
}catch(SQLException e){}
}
public static void close(Statement pstmt){
if(pstmt !=null){
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(ResultSet rs){
if(rs !=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
通过利用ThreadLocal这个类来封装Connection,这样在业务逻辑层获取connection的时候,就会避免了很多麻烦。在遇到多重业务逻辑调用
多种方法时,调用到的connection会在当前线程中查找获取到connection这个对象进行数据库操作。
接下来,就该介绍如何利用动态代理来封装事务了,请见下篇博客!