实现:保证在一个线程里执行Connection,保证事务
下面是FlowCardManagerImpl.java(服务层实现,Manager实现)里面一个“添加流向单”方法的实现:
public void addFlowCard(FlowCard flowCard) throws ApplicationException {
Connection conn = null;
try {
//取得Connection
conn = ConnectionManager.getConnection();
//开启事务
ConnectionManager.beginTransaction(conn);
//生成流向单单号
String flowCardVouNo = flowCardDao.generateVouNo();
//添加流向单主信息
flowCardDao.addFlowCardMaster(flowCardVouNo, flowCard);
//添加流向单明细信息
flowCardDao.addFlowCardDetail(flowCardVouNo, flowCard.getFlowCardDetailList());
//提交事务
ConnectionManager.commitTransaction(conn);
} catch(DaoException e) {
//回滚事务
ConnectionManager.rollbackTransaction(conn);
throw new ApplicationException("添加流向单失败");
} finally {
//关闭Connection并从ThreadLocal中清除
ConnectionManager.closeConnection();
}
}
FlowCardDaoImpl(FlowCardDao实现类)中,生成流向单单号方法中调用“getConnection()”方法。
public String generateVouNo() throws DaoException {
Connection conn = ConnectionManager.getConnection();
//...
return null;
}
ConnectionManager中,getConnection方法定义如下:
private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>(); public static Connection getConnection() {
Connection conn = connectionHolder.get();
//如果在当前线程中没有绑定相应的Connection
if (conn == null) {
try {
JdbcConfig jdbcConfig = XmlConfigReader.getInstance().getJdbcConfig();
Class.forName(jdbcConfig.getDriverName());
conn = DriverManager.getConnection(jdbcConfig.getUrl(), jdbcConfig.getUserName(), jdbcConfig.getPassword());
//将Connection设置到ThreadLocal中
connectionHolder.set(conn);
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new ApplicationException("系统错误,请联系系统管理员!");
} catch (SQLException e) {
e.printStackTrace();
throw new ApplicationException("系统错误,请联系系统管理员!");
}
}
return conn;
}
那么,添加流向单服务(Manager)的运行过程如下:
(1)取得Connection,conn = ConnectionManager.getConnection();
(2)开启事务,ConnectionManager.beginTransaction(conn);
(3)调用生成流向单单号方法flowCardDao.generateVouNo()
(4)generateVouNo()方法的实现中,Connection conn = ConnectionManager.getConnection();
(5)ConnectionManager类的getConnection()方法:
i 如果存在Connection,则从ThreadLocal中取得Connection
ii 如果不存在Connection,则创建一个Connection,将Connection设置到ThreadLocal中
iii 返回Connection
(6)因为在第一步中(Manager层)已经创建Connection,所以在Dao层实现中只需取得ThreadLocal中的Connection。
(7)Manager层的添加流向单主信息和添加流向单明细信息方法同生成流向单号方法,都是取得ThreadLocal中的Connection。
(8)从而实现了“保证在一个线程里执行Connection,保证事务”