一
在Spring中配置事務管理器
事務管理器bean的聲明
?<bean id=
transactionManager
class=
org
springframework
orm
hibernate
HibernateTransactionManager
>
? <property name=
sessionFactory
ref=
sessionFactory
/>
?bean>
如果你需要以標注驅動的方式管理的話
必須在applicationContext
xml中申明
<tx:annotation
driven transaction
manager=
transactionManager
/>
如果你用xml的方式使用事務管理器的話
如下有一個例子
?<tx:advice id=
txAdvice
transaction
manager=
transactionManager
>
? <tx:attributes>
? <tx:method name=
find*
read
only=
true
/>
? <tx:method name=
*
propagation=
REQUIRED
/>
? tx:attributes>
?tx:advice>
??<aop:config>
? <aop:pointcut expression=
execution(* *dao
impl*())
id=
dao
pc
/>
? <aop:pointcut expression=
execution(* *service
impl*())
id=
service
pc
/>
? <aop:advisor advice
ref=
txAdvice
pointcut
ref=
dao
pc
/>
? <aop:advisor advice
ref=
txAdvice
pointcut
ref=
service
pc
/>
?aop:config>
?<aop:aspectj
autoproxy />
二
在java代碼中指定事務屬性(使用標注)
下面例子是Dao實現類的一個方法
采用標注來指明事務
?@Transactional(readOnly=true)
?public List<User> findUser(UserDto dto) {
? User user = new User()
? pyProperties(dto
user)
? return factory
getCurrentSession()
?
createCriteria(User
class)
?
add(Example
create(user))
?
list()
?}
三
Spring事務選項
默認的 @Transactional設置如下
· 事務傳播設置是 PROPAGATION_REQUIRED 使用現有事物
沒有則啟動新事物
· 事務隔離級別是 ISOLATION_DEFAULT
· 事務是 讀/寫 false
· 事務超時默認是依賴於事務系統的
或者事務超時沒有被支持
· 任何unchecked Exception將觸發事務回滾
但是任何checked Exception將觸發事務提交
@Transactional注解的屬性
· 傳播性propagation
可選的傳播性設置
· 隔離性isolation
可選的隔離性級別
· 只讀性readOnly
讀寫型事務 or 只讀型事務
· 回滾異常類rollbackFor
一組異常類
遇到時必須進行回滾
默認情況下checked exceptions不進行回滾而是提交
僅unchecked exceptions才進行事務回滾
· 回滾異常類名rollbackForClassname
一組異常類名
遇到時必須進行回滾
· 不回滾異常類noRollbackFor
一組異常類
遇到時必須不回滾
· 不回滾異常類名noRollbackForClassname
一組異常類
遇到時必須不回滾
Propagation
key屬性確定代理應該給哪個方法增加事務行為
這樣的屬性最重要的部份是傳播行為
有以下選項可供使用
· PROPAGATION_REQUIRED
支持當前事務
如果當前沒有事務
就新建一個事務
這是最常見的選擇
· PROPAGATION_SUPPORTS
支持當前事務
如果當前沒有事務
就以非事務方式執行
· PROPAGATION_MANDATORY
支持當前事務
如果當前沒有事務
就拋出異常
· PROPAGATION_REQUIRES_NEW
新建事務
如果當前存在事務
把當前事務掛起
· PROPAGATION_NOT_SUPPORTED
以非事務方式執行操作
如果當前存在事務
就把當前事務掛起
· PROPAGATION_NEVER
以非事務方式執行
如果當前存在事務
則拋出異常
Isolation Level(事務隔離等級)
· Serializable:最嚴格的級別
事務串行執行
資源消耗最大
· REPEATABLE READ:保證了一個事務不會修改已經由另一個事務讀取但未提交(回滾)的數據
避免了
髒讀取
和
不可重復讀取
的情況
但是帶來了更多的性能損失
· READ COMMITTED:大多數主流數據庫的默認事務等級
保證了一個事務不會讀到另一個並行事務已修改但未提交的數據
避免了
髒讀取
該級別適用於大多數系統
· Read Uncommitted:保證了讀取過程中不會讀取到非法數據
隔離級別在於處理多事務的並發問題
我們知道並行可以提高數據庫的吞吐量和效率
但是並不是所有的並發事務都可以並發運行
這需要查看數據庫教材的可串行化條件判斷了
我們首先說並發中可能發生的
中不討人喜歡的事情
· Dirty reads
讀髒數據
也就是說
比如事務A的未提交(還依然緩存)的數據被事務B讀走
如果事務A失敗回滾
會導致事務B所讀取的的數據是錯誤的
· non
repeatable reads
數據不可重復讀
比如事務A中兩處讀取數據
total
的值
在第一讀的時候
total是
然後事務B就把total的數據改成
事務A再讀一次
結果就發現
total竟然就變成
了
造成事務A數據混亂
· phantom reads
幻象讀數據
這個和non
repeatable reads相似
也是同一個事務中多次讀不一致的問題
但是non
repeatable reads的不一致是因為他所要取的數據集被改變了(比如total的數據)
但是phantom reads所要讀的數據的不一致卻不是他所要讀的數據集改變
而是他的條件數據集改變
比如Select account
id where account
name=
ppgogo*
第一次讀去了
個符合條件的id
第二次讀取的時候
由於事務b把一個帳號的名字由
dd
改成
ppgogo
結果取出來了
個數據
readOnly
事務屬性中的readOnly標志表示對應的事務應該被最優化為只讀事務
這是一個最優化提示
在一些情況下
一些事務策略能夠起到顯著的最優化效果
例如在使用Object/Relational映射工具(如
Hibernate或TopLink)時避免dirty checking
readOny只是一種
暗示
具體會不會起到優化的效果還取決於數據庫
Timeout
在事務屬性中還有定義
timeout
值的選項
指定事務超時為幾秒
在JTA中
這將被簡單地傳遞到J
EE服務器的事務協調程序
並據此得到相應的解釋
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28239.html