自己動手實現簡單的事務管理(動態代理+註解)一
阿新 • • 發佈:2019-01-06
使用原生的servlet,沒有使用框架。運用動態代理技術手動實現service層的事務管理。並增加註解功能,用於查詢時無需事務管理。
事務管理需要保證連線Connection的一致,即dao層和service層的connection是同一個,這就需要用到ThreadLocal處理。直接上程式碼:
public class ThreadLocalJDBCUtils {
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
private static DataSource dataSource;
static {
try {
//手動載入配置檔案,初始化druid連線池
Properties pro = new Properties();
InputStream in = ThreadLocalJDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(in);
dataSource = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 獲得連線池方法
* @return 資料連線池
*/
public static DataSource getDataSource(){
return dataSource;
}
/**
* 獲得連線物件方法
* @return 連線物件
*/
public static Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException("獲取連線失敗");
}
}
/**
* 獲得與執行緒繫結的connection
* @return connection
*/
public static Connection getCurrentConnection() {
Connection connection = threadLocal.get();
if(connection==null){
connection = getConnection();
threadLocal.set(connection);
}
return connection;
}
/**
* 開啟事務
*/
public static void beginTransaction(){
try {
getCurrentConnection().setAutoCommit(false);
} catch (SQLException e) {
throw new RuntimeException("開啟事務失敗");
}
}
/**
* 回滾事務
*/
public static void rollback(){
try {
getCurrentConnection().rollback();
} catch (SQLException e) {
throw new RuntimeException("回滾事務失敗");
}
}
/**
* 提交事務
*/
public static void commit(){
try {
getCurrentConnection().commit();//事務提交
} catch (SQLException e) {
throw new RuntimeException("提交事務失敗");
}
}
/**
* 釋放資源
*/
public static void close(){
Connection currentConnection = getCurrentConnection();
try {
currentConnection.close();
threadLocal.remove();//從執行緒中刪除
} catch (SQLException e) {
throw new RuntimeException("釋放資源失敗");
}
}
}
使用了druid連線池,druid.properties
配置如下:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///test01
username=root
password=123
initialSize=5
maxActive=10
maxWait=3000
說明:每次使用此工具類時使用getCurrentConnection(),獲得與執行緒繫結的連線物件。第一次,執行緒中沒有connection時從連線池中獲得連線並存到執行緒中。釋放資源時把連線從執行緒中移除。重點不在於此,工具類直接複製也行。注意配置好自己的資料庫。
測試utils,列印connection,沒有報錯打印出地址說明是成功的
public class UtilsTest {
public static void main(String[] args) {
Connection connection = ThreadLocalJDBCUtils.getCurrentConnection();
System.out.println(connection);
}
}