[Java]具备全程事务控制的JDBC连接管理器(二)

2014-11-24 10:43:53 · 作者: · 浏览: 1
ThreadLocal),这样可以保证为每一个线程存储单个不同的连接对象

[java]
// 线程本地对象管理器
private static final ThreadLocal connectionHolder = new ThreadLocal<>();// 数据源private DataSource dataSource;
  数据源对象由构造器来注入,在getConnection方法中,从线程本地存储中获取一个现存的数据库连接对象或者从数据源中建立一个新的数据库连接对象
[java]
public Connection getConnection() throws SQLException {
Connection connection = connectionHolder.get();
if (connection == null) {
connection = dataSource.getConnection();
connectionHolder.set(connection);
}
return connection;
}
  这样,只要数据库连接不被关闭,就可以在一个线程内一直获取相同的数据库连接对象
  同样,beginTransaction方法会通过getConnection方法获取一个数据库连接对象,并在其之上启动事务。由此一来,只要不关闭数据库连接对象,则再次调用getConnection方法获取的数据库连接对象,都会存在于相同的事务中。
  beginTransaction方法返回的是一个Transaction接口单例对象,该接口被作为ConnectionManager类的内嵌类来实现,其作用是通过ConnectionManager类中的线程本地存储对象获取之前产生的数据库连接对象。

  Transaction接口定义如下:

[java]
package edu.softparty.base.dbunit;

import java.sql.SQLException;

public interface Transaction {
void commit() throws SQLException;
void rollback() throws SQLException;
}
  该接口在ConnectionManager类中被实现如下:
实现一:

[java]
private static final Transaction TRANSACTION = new Transaction() {
public void rollback() throws SQLException {
Connection connection = connectionHolder.get();
if (connection != null) {
if (connection.getAutoCommit() == false) {
connection.rollback();
}
connection.close();
connectionHolder.remove();
}
}

public void commit() throws SQLException {
Connection connection = connectionHolder.get();
if (connection != null) {
if (connection.getAutoCommit() == false) {
connection.commit();
}
connection.close();
connectionHolder.remove();
}
}
};
  实现一中,内嵌类通过其外部类ConnectionManager的线程本地存储对象获取数据库连接对象,如能正确获取且连接对象上启动了事务,则进行事务的回滚或提交,并在操作完毕后关闭数据库连接并将连接对象从线程本地存储对象中删除,防止该连接被再次获取和使用。

实现二:
[java]
private static final Transaction EMPTY_TRANSACTION = new Transaction() {
public void rollback() throws SQLException {
}
public void commit() throws SQLException {
}
};
  实现二是一个伪实现,其目的就是为了什么也不做,这样一来就可以在ConnectionManager类的getTransaction方法中获取一个合适的Transaction接口对象
[java]
public Transaction getTransaction() {
return connectionHolder.get() == null EMPTY_TRANSACTION : TRANSACTION;
}
  即在获取事务对象时,如果数据库连接存在,则返回可以操作事务的Transaction对象,否则返回伪实现对象,以保证返回的结果上可以正确调用rollback和commit方法。
  在数据库链接使用完毕后,可以通过提交/回滚事务或者close方法对连接进行释放,连接一旦关闭则将连接对象从本地线程存储中移除,再次调用getConnection方法时又会获取一个新的数据库连接对象。


[java]
public void close() throws SQLException {
Connection connection = connectionHolder.get();
if (connection != null) {
connection.close();
connectionHolder.remove();
}
}
  通过这个连接管理器,可以保证在同一线程的任意方法中获取连接、启动事务,在其它方法中都可以进行事务的回滚、提交或连接关闭操作。

  配
package edu.softparty.base.dbunit;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.tomcat.dbcp.dbcp.BasicDataSource;

/**
* 数据连接工厂类
*/
public class ConnectionFactory {

// 单例工厂类对象
private static ConnectionManager connectionManager = null;

/**
* 私有构造器
*/
private ConnectionFactory() {
}

/**
* 创建连接管理