原生的jdbc 對事務管理也是比較繁瑣的, 需要手工進行提交和回滾, 還要一堆try-catch. 而熟悉spring 的同學都知道, spring採用了宣告式事務方式來管理事務, 使事務管理變得很簡單. spring 事務很強大, 筆者這裡僅使用jdbc 來模擬簡單的幾個屬性.
筆者對資料庫的連線採用c3p0 連線池.
<?xml version="1.0" encoding="utf-8"?>
>
name
="myc3p0pool"
>
name
="user"
>
rootproperty
>
name
="password"
>
rootproperty
>
name
="driverclass"
>
com.mysql.jdbc.driverproperty
>
name
="jdbcurl"
>
jdbc:mysql://localhost:3306/learn-jdbc?characterencoding=utf-8property
>
name
="acquireincrement"
>
10property
>
name
="initialpoolsize"
>
5property
>
name
="minpoolsize"
>
5property
>
name
="maxpoolsize"
>
50property
>
name
="maxstatements"
>
100property
>
name
="maxstatementsperconnection"
>
10property
>
named-config
>
c3p0-config
>
封裝獲取資料庫連線和關閉資料庫連線資源的方法
public
class
dbconnutil
catch
(sqlexception e)
return null;
}/**
* @description: 獲取本執行緒連線
* @return: connection 資料庫連線
* @author: zongf
* @time: 2019-06-26 14:37:00
* @since 1.0
*/public
static txconnection gettxconnection()
else
return txconnection;
}/** 獲取當前執行緒內的資料庫連線
* @return connection
* @since 1.0
* @author zongf
* @created 2019-07-18
*/public
static connection getlocalconnection()
/** 獲取當前執行緒的資料庫連線物件
* @return threadlocal* @since 1.0
* @author zongf
* @created 2019-07-18
*/public
static threadlocal
getlocaltxconnection()
/** 當歸還連線時, 需要設定自動提交事務為true.
* @param connection
* @return null
* @since 1.0
* @author zongf
* @created 2019-07-18
*/public
static
void
release
(connection connection)
throws sqlexception
}catch
(sqlexception e)
finally
}}
由於在事務巢狀時, 需要遵循哪一層動態**開啟的事務, 由哪一層動態**負責事務的開啟和回滾, 因此需要記錄事務的開啟者. 因此筆者建立了乙個txconnneciton 物件.
public
class
txconnection
@documented
@target
(elementtype.method)
@retention
(retentionpolicy.runtime)
public @inte***ce
enabletranscation
/**事務動態**處理器
* @since 1.0
* @author zongf
* @created 2019-07-18
*/public
class
transcationhandler
implements
invocationhandler
public object invoke
(object proxy, method method, object[
] args)
throws throwable
}else
}// 執行目標方法
object object = targetmethod.
invoke
(this
.target, args)
;// 如果事務是當前handler物件建立, 那麼提交事務if(
this
.tostring()
.equals
(txconnection.
getcreator()
))return object;
}catch
(exception e)
}throw
newruntimeexception
("發生異常, 事務已回滾!"
, e);}
finally
// 如果新連線不為null, 則表示開啟了新事務. 則回滾原連線
if(oldtxconnection != null)}}
}
建立service 工廠類, 用於模擬spring 容器. 當目標service中包含@enabletransaction 註解時, 建立service 的動態**, 否則建立service 物件.
/** service工廠, 模擬spring 容器
* @since 1.0
* @author zongf
* @created 2019-07-18
*/public
class
servicefactory
catch
(exception e)
// 判斷不能是介面, 介面不能建立實現類
if(clz.
isinte***ce()
)// 是否開啟動態**
boolean enabletx =
false
;// 遍歷所有非私有方法, 如果方法有@enabletx註解, 則說明需要建立**
method[
] methods = clz.
getmethods()
;for
(method method : methods)
}// 如果需要建立**, 則返回**物件
if(enabletx)
return t;
}}
測試用例, 筆者借助於之前寫的basedao來簡化基本步驟的開發.
public
inte***ce
imixservice
public
class
mixservice
implements
imixservice
@enabletranscation
@override
public
void
error()
@override
public
void
show()
}
public
class
mixservice
implements
imixservice
@enabletranscation
@override
public
void
error()
@override
public
void
show()
}
Spring 注入實現類報錯問題
在使用spring 時,假如在controller中注入了impl 實現類可能會出現報錯的情況。為什麼是 可能 假如沒用使用spring aop 則不會報錯。類沒用使用介面也不會報錯。1 為什麼使用 aop 會導致報錯 spring aop的實現是基於動態 如果目標物件實現了介面,那麼在預設情況下會...
JDBC 自定義工具類 實現登入
一 配置檔案 jdbc1.properties url 本地資料庫位址 user 資料庫的賬號 password 資料庫的密碼 driver 註冊位址 url jdbc mysql localhost 3306 db1?servertimezone gmt 2b8user root password...
C 類和物件實戰之Date類的實現方法
目錄 在學了c 類和物件基本知識以及六個預設成員函式後,我們可以上手實現乙個date類出來,檢驗學習的效果。介面展示 class date 設定成靜態避免重複建立 int dabcpgdvy monthdays month 對閏年二月的處理 if month 2 year 4 0 year 100 ...