Java開發學習(二十二)——Spring事務屬性、事務傳播行為

一、事務配置

Java開發學習(二十二)——Spring事務屬性、事務傳播行為

上面這些屬性都可以在

@Transactional

註解的引數上進行設定。

readOnly:true只讀事務,false讀寫事務,增刪改要設為false,查詢設為true。

timeout:設定超時時間單位秒,在多長時間之內事務沒有提交成功就自動回滾,-1表示不設定超時時間。

rollbackFor:當出現指定異常進行事務回滾

noRollbackFor:當出現指定異常不進行事務回滾

思考:出現異常事務會自動回滾,這個是我們之前就已經知道的

noRollbackFor是設定對於指定的異常不回滾,這個好理解

rollbackFor是指定回滾異常,對於異常事務不應該都回滾麼,為什麼還要指定?

這塊需要更正一個地方,並不是所有的異常都會回滾事務,比如下面的程式碼就不會回滾

public interface AccountService { /** * 轉賬操作 * @param out 傳出方 * @param in 轉入方 * @param money 金額 */ //配置當前介面方法具有事務 public void transfer(String out,String in ,Double money) throws IOException; } @Service public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; @Transactional public void transfer(String out,String in ,Double money) throws IOException{ accountDao。outMoney(out,money); //int i = 1/0; //這個異常事務會回滾 if(true){ throw new IOException(); //這個異常事務就不會回滾 } accountDao。inMoney(in,money); } }

出現這個問題的原因是,Spring的事務只會對

Error異常

RuntimeException異常

及其子類進行事務回顧,其他的異常型別是不會回滾的,對應IOException不符合上述條件所以不回滾

此時就可以使用rollbackFor屬性來設定出現IOException異常不回滾

@Service

public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; @Transactional(rollbackFor = {IOException。class}) public void transfer(String out,String in ,Double money) throws IOException{ accountDao。outMoney(out,money); //int i = 1/0; //這個異常事務會回滾 if(true){ throw new IOException(); //這個異常事務就不會回滾 } accountDao。inMoney(in,money); } }

rollbackForClassName等同於rollbackFor,只不過屬性為異常的類全名字串

noRollbackForClassName等同於noRollbackFor,只不過屬性為異常的類全名字串

isolation設定事務的隔離級別

DEFAULT :預設隔離級別, 會採用資料庫的隔離級別

READ_UNCOMMITTED : 讀未提交

READ_COMMITTED : 讀已提交

REPEATABLE_READ : 重複讀取

SERIALIZABLE: 序列化

介紹完上述屬性後,還有一個事務的傳播行為,先看下面的案例

二、轉賬業務追加日誌案例

2。1 需求分析

在上節部落格(

Java開發學習(二十一)——Spring事務簡介與事務角色解析

)環境的基礎上新增新的需求,完成轉賬後記錄日誌。

需求:實現任意兩個賬戶間轉賬操作,並對每次轉賬操作在資料庫進行留痕

需求微縮:A賬戶減錢,B賬戶加錢,資料庫記錄日誌

基於上述的業務需求,我們來分析下該如何實現:

①:基於轉賬操作案例新增日誌模組,實現資料庫中記錄日誌

②:業務層轉賬操作(transfer),呼叫減錢、加錢與記錄日誌功能

需要注意一點就是,我們這個案例的預期效果為:

無論轉賬操作是否成功,均進行轉賬操作的日誌留痕

2。2 環境準備

環境參考

Java開發學習(二十一)——Spring事務簡介與事務角色解析

在其基礎上,我們繼續往下寫

步驟1:建立日誌表

create table tbl_log( id int primary key auto_increment, info varchar(255), createDate datetime )

步驟2:新增LogDao介面

public interface LogDao { @Insert(“insert into tbl_log (info,createDate) values(#{info},now())”) void log(String info); }

步驟3:新增LogService介面與實現類

public interface LogService { void log(String out, String in, Double money); } @Service public class LogServiceImpl implements LogService { @Autowired private LogDao logDao; @Transactional public void log(String out,String in,Double money ) { logDao。log(“轉賬操作由”+out+“到”+in+“,金額:”+money); } }

步驟4:在轉賬的業務中新增記錄日誌

public interface AccountService { /** * 轉賬操作 * @param out 傳出方 * @param in 轉入方 * @param money 金額 */ //配置當前介面方法具有事務 public void transfer(String out,String in ,Double money)throws IOException ; } @Service public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; @Autowired private LogService logService; @Transactional public void transfer(String out,String in ,Double money) { try{ accountDao。outMoney(out,money); accountDao。inMoney(in,money); }finally { logService。log(out,in,money); } } }

步驟5:執行程式

當程式正常執行,tbl_account表中轉賬成功,tbl_log表中日誌記錄成功

當轉賬業務之間出現異常(int i =1/0),轉賬失敗,tbl_account成功回滾,但是tbl_log表未新增資料

這個結果和我們想要的不一樣,什麼原因?該如何解決?

失敗原因:日誌的記錄與轉賬操作隸屬同一個事務,同成功同失敗

最終效果:無論轉賬操作是否成功,日誌必須保留

三、事務傳播行為

Java開發學習(二十二)——Spring事務屬性、事務傳播行為

對於上述案例的分析:

log方法、inMoney方法和outMoney方法都屬於增刪改,分別有事務T1,T2,T3

transfer因為加了@Transactional註解,也開啟了事務T

前面我們講過Spring事務會把T1,T2,T3都加入到事務T中

所以當轉賬失敗後,所有的事務都回滾,導致日誌沒有記錄下來

這和我們的需求不符,這個時候我們就想能不能讓log方法單獨是一個事務呢?

要想解決這個問題,就需要用到事務傳播行為,所謂的事務傳播行為指的是:

事務傳播行為:事務協調員對事務管理員所攜帶事務的處理態度。

具體如何解決,就需要用到之前我們沒有說的

propagation屬性

1。修改logService改變事務的傳播行為

@Service public class LogServiceImpl implements LogService { @Autowired private LogDao logDao; //propagation設定事務屬性:傳播行為設定為當前操作需要新事務 @Transactional(propagation = Propagation。REQUIRES_NEW) public void log(String out,String in,Double money ) { logDao。log(“轉賬操作由”+out+“到”+in+“,金額:”+money); } }

執行後,就能實現我們想要的結果,不管轉賬是否成功,都會記錄日誌。

2。事務傳播行為的可選值

Java開發學習(二十二)——Spring事務屬性、事務傳播行為

作者:

|舊市拾荒|

原文連結:

https://www。cnblogs。com/xiaoyh/p/16412565。html