【Java技術点滴】-ThreadLocalパッケージJDBCトランザクション操作

3637 ワード

背景
Javaプログラムの実装では、トランザクションのメカニズムに適用されることが多く、ビジネス層でトランザクションがオープンし、データベース接続を作成し、Dao層メソッドを呼び出してデータベースアクセスを行い、データベース接続ConnectionをパラメータとしてDao層メソッドに渡す必要があります.このような実装はDaoレイヤメソッドの多重化に不利であることは明らかであり、トランザクションを使用しない場合、Daoレイヤメソッドでデータベース接続を作成する必要がある.これにより、DaoレイヤメソッドはConnectionパラメータを免除し、メソッドをより独立し、明確にすることができ、このような気まずい状況をどのように解決するか.これに対してThreadLocalを用いて解決した.
基本的な紹介
「ローカルスレッド変数」は、変数をThreadLocalに配置し、同じスレッドで共有し、マルチスレッド間でリソースが分離され、相互に干渉せず、スレッドの安全を保証すると理解できます.ThreadLocalを1つのMapタイプと見なすことができ、キー値ペアにアクセスするように格納・取得することと理解できるが、明確にする必要があるのは、1つのThreadLocalを決定した後、そのうち1つのキー値ペアしかアクセスできないため、その読み取り・取得方法も比較的簡単である:get、set方法--スレッド変数の値を読み取り、設定する;removeメソッド--このスレッドのローカル変数の現在のスレッドの値を削除します.initialValue-このスレッドのローカル変数の現在のスレッドの初期値を返します.
パッケージ接続
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 *   ThreadLocal  Connection
 * 
 * @author Administrator
 *
 */
public class ConnectionManager {

	//  ThreadLocal    ,       Connection
	private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>();
	
	/**
	 *   Connection
	 * @return
	 */
	public static Connection getConnection() {
		Connection conn = connectionHolder.get();
		//               Connection
		if (conn == null) {
			try {
				Class.forName("oracle.jdbc.driver.OracleDriver");
				String url = "jdbc:oracle:thin:@localhost:1521:bjpowern";
				String username = "drp1";
				String password = "drp1";
				conn = DriverManager.getConnection(url, username, password);
				// Connection   ThreadLocal
				connectionHolder.set(conn);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return conn;
	}
	
	/**
	 *          
	 * @return
	 */
	public static void closeConnection() {
		Connection conn = connectionHolder.get();
		if (conn != null) {
			try {
				conn.close();
				// ThreadLocal   Connection
				connectionHolder.remove();
			} catch (SQLException e) {
				e.printStackTrace();
			}	
		}
	}
	
	/**
	 *          
	 * @return
	 */
	public static void close(Connection conn) {
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	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();
			}
		}
	}
	
	/**
	 *     
	 * @return
	 */
	public static void beginTransaction(Connection conn) {
		try {
			if (conn != null) {
				if (conn.getAutoCommit()) {
					conn.setAutoCommit(false); //    
				}
			}
		}catch(SQLException e) {}
	}
	
	/**
	 *     
	 * @return
	 */
	public static void commitTransaction(Connection conn) {
		try {
			if (conn != null) {
				if (!conn.getAutoCommit()) {
					conn.commit();
				}
			}
		}catch(SQLException e) {}
	}
	
	/**
	 *     
	 * @return
	 */
	public static void rollbackTransaction(Connection conn) {
		try {
			if (conn != null) {
				if (!conn.getAutoCommit()) {
					conn.rollback();
				}
			}
		}catch(SQLException e) {}
	}	
}

以上のパッケージを経て、ConnectionManagerクラスはスレッド内のConnectionの作成と取得を制御し、Dao層メソッドはConnectionパラメータを渡す必要がなくビジネスロジック層がトランザクションを制御する効果を達成し、ThreadLocalは他の多くの場合に使用することができ、後の使用で説明する.
まとめ
マルチスレッドは高同時時によく使われる技術を解決し、スレッド間の資源共有を明確にし、資源間の協調を合理的に分配し、制御すれば、多くのスレッドを使用することができ、マルチスレッドを応用する前提でもあり、この面ではまだ不足しており、多くの蓄積学習が行われている.