[b]背景:[/b]
[color=red]目前有一个系统,系统已经写好了,但是要不停的添加新的功能,用Struts,
业务逻辑写在Action中,以后可能增加一层Service。
业务处理和持久层没有使用任何框架,目前是用Dao担任业务处理加持久层双重操作,
但是有些业务处理很复杂,固设计了一个事务处理框架,大家帮我看下有没有线程安全的问题,
第一次使用ThreadLocal,请多指教。[/color]
[b]Connection Holder 代码[/b]
[code]public class ConnectionHolder {
private Connection connection = null;
private boolean rollback = false;
private boolean isreadonly = false;
public boolean isIsreadonly() {
return isreadonly;
}
public void setIsreadonly(boolean isreadonly) {
this.isreadonly = isreadonly;
}
public Connection getConnection() {
if (null == connection)
throw new RuntimeException("connection not exist........");
return connection;
}
public void setConnection(Connection connection) {
this.connection = connection;
}
public boolean isRollback() {
return rollback;
}
public void setRollback(boolean rollback) {
this.rollback = rollback;
}
}[/code]
[b]TransactionManager 代码[/b]
[code]public class TransactionManager {
private static final Log logger = LogFactory
.getLog(TransactionManager.class);
private static ThreadLocal _thread = new ThreadLocal();
private static void safeCloseConnection(Connection con) {
try {
if (null != con)
con.close();
con = null;
} catch (Exception e) {
logger.error("", e);
}
}
public static void begin() {
begin(false);
}
public static void begin(boolean isReadonly) {
ConnectionHolder holder = null;
Connection con = null;
try {
con = JNDIUtils.getConnection();
if (!isReadonly) {
con.setAutoCommit(false);
}
holder = new ConnectionHolder();
holder.setConnection(con);
holder.setIsreadonly(isReadonly);
_thread.set(holder);
} catch (Exception e) {
safeCloseConnection(con);
logger.error("", e);
throw new RuntimeException();
}
}
private static void commit() {
ConnectionHolder holder = null;
Connection con = null;
try {
holder = getConnectionHolder();
con = holder.getConnection();
if (!holder.isRollback() && !holder.isIsreadonly()) {
con.commit();
con.setAutoCommit(true);
}
} catch (Exception e) {
logger.error("", e);
} finally {
safeCloseConnection(con);
}
}
public static void end() {
commit();
}
public static void rollback() {
ConnectionHolder holder = null;
Connection con = null;
try {
holder = getConnectionHolder();
holder.setRollback(true);
con = holder.getConnection();
if (holder.isIsreadonly()) {
throw new RuntimeException("readonly cannot rollback....");
}
con.rollback();
con.setAutoCommit(true);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
logger.error("", e);
} finally {
safeCloseConnection(con);
}
}
private static ConnectionHolder getConnectionHolder() {
ConnectionHolder holder = (ConnectionHolder) _thread.get();
if (null != holder)
return holder;
throw new RuntimeException("connection holder not exist.......");
}
public static Connection openConnection() {
Connection con = getConnectionHolder().getConnection();
if (null != con)
return con;
throw new RuntimeException("connection not exist.......");
}
}[/code]
[b]Action 部分代码[/b]
[code]public ActionForward deleteResourceXqzy(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
try {
TransactionManager.begin(); //事务开始
/**
多次DAO代码调用
业务处理
多次DAO代码调用
*/
} catch (Exception ex) {
TransactionManager.rollback(); //事务回滚
//其它操作
} finally {
TransactionManager.end(); //事务提交
//其它操作
}
return mapping.findForward("test");
}[/code]
[b]DAO 部分代码[/b]
[code]public static void deleteResourceZyfb() throws Exception {
String sql = null;
PreparedStatement ps = null;
try {
Connection con = TransactionManager.openConnection();
sql = "";
ps = con.prepareStatment(sql);
ps.executeUpdate();
} finally {
safeCloseStatementOrRs(ps);
}
}[/code]
[color=red]目前有一个系统,系统已经写好了,但是要不停的添加新的功能,用Struts,
业务逻辑写在Action中,以后可能增加一层Service。
业务处理和持久层没有使用任何框架,目前是用Dao担任业务处理加持久层双重操作,
但是有些业务处理很复杂,固设计了一个事务处理框架,大家帮我看下有没有线程安全的问题,
第一次使用ThreadLocal,请多指教。[/color]
[b]Connection Holder 代码[/b]
[code]public class ConnectionHolder {
private Connection connection = null;
private boolean rollback = false;
private boolean isreadonly = false;
public boolean isIsreadonly() {
return isreadonly;
}
public void setIsreadonly(boolean isreadonly) {
this.isreadonly = isreadonly;
}
public Connection getConnection() {
if (null == connection)
throw new RuntimeException("connection not exist........");
return connection;
}
public void setConnection(Connection connection) {
this.connection = connection;
}
public boolean isRollback() {
return rollback;
}
public void setRollback(boolean rollback) {
this.rollback = rollback;
}
}[/code]
[b]TransactionManager 代码[/b]
[code]public class TransactionManager {
private static final Log logger = LogFactory
.getLog(TransactionManager.class);
private static ThreadLocal _thread = new ThreadLocal();
private static void safeCloseConnection(Connection con) {
try {
if (null != con)
con.close();
con = null;
} catch (Exception e) {
logger.error("", e);
}
}
public static void begin() {
begin(false);
}
public static void begin(boolean isReadonly) {
ConnectionHolder holder = null;
Connection con = null;
try {
con = JNDIUtils.getConnection();
if (!isReadonly) {
con.setAutoCommit(false);
}
holder = new ConnectionHolder();
holder.setConnection(con);
holder.setIsreadonly(isReadonly);
_thread.set(holder);
} catch (Exception e) {
safeCloseConnection(con);
logger.error("", e);
throw new RuntimeException();
}
}
private static void commit() {
ConnectionHolder holder = null;
Connection con = null;
try {
holder = getConnectionHolder();
con = holder.getConnection();
if (!holder.isRollback() && !holder.isIsreadonly()) {
con.commit();
con.setAutoCommit(true);
}
} catch (Exception e) {
logger.error("", e);
} finally {
safeCloseConnection(con);
}
}
public static void end() {
commit();
}
public static void rollback() {
ConnectionHolder holder = null;
Connection con = null;
try {
holder = getConnectionHolder();
holder.setRollback(true);
con = holder.getConnection();
if (holder.isIsreadonly()) {
throw new RuntimeException("readonly cannot rollback....");
}
con.rollback();
con.setAutoCommit(true);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
logger.error("", e);
} finally {
safeCloseConnection(con);
}
}
private static ConnectionHolder getConnectionHolder() {
ConnectionHolder holder = (ConnectionHolder) _thread.get();
if (null != holder)
return holder;
throw new RuntimeException("connection holder not exist.......");
}
public static Connection openConnection() {
Connection con = getConnectionHolder().getConnection();
if (null != con)
return con;
throw new RuntimeException("connection not exist.......");
}
}[/code]
[b]Action 部分代码[/b]
[code]public ActionForward deleteResourceXqzy(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
try {
TransactionManager.begin(); //事务开始
/**
多次DAO代码调用
业务处理
多次DAO代码调用
*/
} catch (Exception ex) {
TransactionManager.rollback(); //事务回滚
//其它操作
} finally {
TransactionManager.end(); //事务提交
//其它操作
}
return mapping.findForward("test");
}[/code]
[b]DAO 部分代码[/b]
[code]public static void deleteResourceZyfb() throws Exception {
String sql = null;
PreparedStatement ps = null;
try {
Connection con = TransactionManager.openConnection();
sql = "";
ps = con.prepareStatment(sql);
ps.executeUpdate();
} finally {
safeCloseStatementOrRs(ps);
}
}[/code]