spring 有一整套的事務管理機制,開發人員在使用的時候不用了解在在底層是怎麼實現的。可以使用這樣的事務機制,處理各種情況下的事務處理
在spring中不同的操作有不同的事務管理器
jdbc事務管理器: datasourcetransactionmanager
hibernate 對應的事務管理器:hibernatetransactionmanager
...
"transactionmanager"
class
="org.springframework.jdbc.datasource.datasourcetransactionmanager"
>
name
="datasource"
ref="datasource"
>
property
>
bean
>
<
tx:annotation-driven
transaction-manager
="transactionmanager"
/>
//在service 層的方法上新增註解@trasactional,就可以實現事務管理
@transactional
public
void
test()
當乙個事務方法中呼叫另乙個事務時,必須指定事務該如何傳播;在註解@transactional 的屬性中propagation進行指定
/*例如,買書作為乙個功能,要完成的資料庫操作是:書本的數量-1,自己的錢減少。這是乙個事務方法*/
@transactional
public
void
buybook()
/* 現在乙個人要買兩本書,這也是乙個事務方法,並且這個方法中要呼叫buybook*/
@transactional
public
void
buybooks()
/*** 現在一本書10 但是只有15 塊錢,執行的結果會是一本書都沒有買到
* 原因: transaction 的預設傳播屬性 propagation=propagation.required
transactional的預設傳播屬性propagation=propagation.required
表示:使用呼叫方法的事務(也可以看成:忽視了被呼叫方法的事務宣告)
transactional的傳播屬性propagation=propagation.requires_new
表示:該方法必須開啟乙個新的事務,並在自己的事務中執行,如果當前被呼叫事務正在執行,那麼呼叫方法的事務要掛起
@transactional
(propagation =propagation.requires_new)
public
void
buybooks()
/* 現在一本書10 但是只有15 塊錢,執行的結果會是買到了一本書,第二本書沒有買到
*buybooks 事務開始,buybook 事務開始,buybooks 事務掛起;buybook 事務結束,buybooks 事務繼續,buybook 事務開始,因為錢不夠,buybook 事務回滾,回滾到當前的buybook 事務開始的地方,buybook 事務結束,buybooks 事務開始
* 知道buybooks 執行結束 buybooks 事務結束
* buybooks 本身時有事務的,因為事務傳播屬性propagation = propagation.requires_new 會在buybooks 事務中新開乙個事務buybook 並且在buybooks 事務中執行
*/
併發事務所導致的問題,當乙個或多個應用程式中的多個事務在同乙個資料集上併發執行時,可能會發生許多的意外問題(髒讀,不可重複讀,幻讀)
使用@transactional 的屬性isolation指定提交級別isolation=isolation.red_committed
讀已提交
spring 預設情況下對所有的執行時異常進行回滾,也可以通過屬性的是設定,指定對那些異常進行回滾,對那些異常不進行回滾
/*涉及的屬性*/
對那些異常進行回滾 rollbackfor=
rollbackforclassname
norollbackfor norollbackforclassname
/*一般不會對這個屬性進行設定,使用預設的出現執行時異常就進行回滾*/
設定readonly屬性readonly = true
表示這個事務只讀取資料不糊更新資料,這樣可以幫助資料庫引擎優化事務;當這個事務確實為乙個唯讀屬性的時候就要進行這樣的設定
設定timeout屬性,timeout= 秒數
,事務的執行之間超過timeout 的設定時間,就會被強制回滾(儘管沒有異常)
在買書的buybook 事務中新增**,進行測試
@transactional
(timeout=2)
public
void
buybook()
catch
(exception ex)
/*此時你買一本書,你還有15塊錢,你也無法購買成功,因為,設定的最長時間是2s 但是函式中設定了睡眠時間4s 事務的存在時間超過了2s 就會被強制回滾*/
/* 好處在於: 在這種情況下 減少事務的占用時間*/
首先配置需要的bean
配置事務管理器
"transactionmanager"
class
="org.springframework.jdbc.datasource.datasourcetransactionmanager"
>
name
="datasource"
ref="datasource"
>
property
>
bean
>
配置事務屬性
"transactionmanager"
class
="org.springframework.jdbc.datasource.datasourcetransactionmanager"
>
name
="datasource"
ref="datasource"
>
property
>
bean
>
<
tx:advice
transaction-manager
="transactionmanager"
id="txadvice"
>
<
tx:attributes
>
<
tx:method
name
="testtwo"
propagation
="requires_new"
/>
<
tx:method
name
="方法名"
相應的屬性配置
/>
<
tx:method
name
="get*"
readonly
="true"
/>
tx:attributes
>
tx:advice
>
<
aop:config
>
<
aop:pointcutid=
"pointcut"
expression
="execution(* spring.aop.test.jdbctemplatetest.testtwo(..))"
/>
<
aop:advisor
advice-ref
="txadvice"
pointcut-ref
="pointcut"
/>
aop:config
>
Spring複習筆記 Spring中的Bean
注意構造器例項化 最常用 靜態工廠方式例項化 例項工廠方式例項化 singleton 單例 始終使用的同乙個物件 預設 prototype 原型 每次都是乙個新的bean例項 request session globalsession websocket init method屬性 用於指定bean...
Spring中 Transactional的使用
1.在需要事務管理的地方加 transactional註解,transactional 註解可以被應用於介面定義和介面方法 類定義和類的 public 方法上.2.transactional 註解只能應用到 public 可見度的方法上,如果你在 protected private 或者 packa...
Spring中 Transactional失效問題
spring中的宣告式註解 transactional很大程度的方便了開發者進行db資料儲存。但是在一些特殊情況下,可能會造成註解不是按想定的方式生效,這裡說幾種可能造成的幾種情況。這是一種比較簡單不過稍不注意也可能會犯的情況。spring中事務提交還是回滾是根據呼叫的方法是否丟擲異常來決定的,因此...