SpringBoot新增事務管理
在啟動類上加入@EnableTransactionManagement
package com.yl.j2005.spc.emp.providerserver;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
@SpringBootApplication
@EnableEurekaClient
@MapperScan(basePackages = "com.yl.j2005.spc.emp.providerserver.mapper")
@EnableTransactionManagement //加入事務管理
public class SpcEmpProviderServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpcEmpProviderServerApplication.class, args);
}
}
再所需加入事務的資料庫管理操作上加入 @Transactional(propagation= Propagation.REQUIRED,isolation = Isolation.DEFAULT,rollbackFor=Exception.class)
propagation引數,Propagation型別(列舉),預設值為Propogation.REQUIRED,支援的值有REQUIRED、MANDATORY、NESTED、NEVER、NOT_SUPPORTED、REQUIRE_NEW、SUPPORTS。
//propagation值得是事務的傳播性
//所謂事務傳播性,就是被呼叫者的事務與呼叫者的事務之間的關係。舉例說明。
//in A.java
Class A {
@Transactional(propagation=propagation.REQUIRED)
public void aMethod {
B b = new B();
b.bMethod();
}
}
//in B.java
Class B {
@Transactional(propagation=propagation.REQUIRED)
public void bMethod { //something }
}
在上面這個例子中,傳播性被設為了REQUIRED,注意,這是預設值,也即不進行該引數配置等於配置成REQUIRED。
REQUIRED的含義是,支援當前已經存在的事務,如果還沒有事務,就建立一個新事務。在上面這個例子中,假設呼叫aMethod前不存在任何事務,那麼執行aMethod時會自動開啟一個事務,而由aMethod呼叫bMethod時,由於事務已經存在,因此會使用已經存在的事務(也就是執行aMethod之前建立的那個事務)。
對於這樣的配置,如果bMethod過程中發生異常需要回滾,那麼aMethod中所進行的所有資料庫操作也將同時被回滾,因為這兩個方法使用了同一個事務。
MANDATORY的含義是,支援當前已經存在的事務,如果還沒有事務,就丟擲一個異常。如果上例中aMethod的傳播性配置為MANDATORY,我們就無法在沒有事務的情況下呼叫aMethod,因此,傳播性為MANDATORY的方法必定是一個其他事務的子事務,當邏輯上獨立存在沒有意義或者可能違反資料、事務完整性的時候,就可以考慮設定這樣的傳播性設定。
NESTED的含義是,在當前事務中建立一個巢狀事務,如果還沒有事務,那麼就簡單地建立一個新事務。
REQUIRES_NEW的含義是,掛起當前事務,建立一個新事務,如果還沒有事務,就簡單地建立一個新事務。
請注意以上兩者的區別,大多數情況下一上兩種傳播性行為是類似的,不過在事務回滾的問題上,以上兩者有很大的區別。
首先,REQUIRES_NEW會建立一個與原事務無關的新事務,儘管是由一個事務呼叫了另一個事務,但卻沒有父子關係。
如果bMethod的傳播性是REQUIRES_NEW,而丟擲了一個異常,則bMethod一定會被回滾,而如果aMethod捕獲並處理了這個bMethod丟擲的異常,那麼aMethod仍有可能成功提交。當然,如果aMethod沒有處理這個異常,那麼aMethod也會被回滾。
如果aMethod在bMethod完成後出現了異常,那麼bMethod已經提交而無法回滾,只有aMethod被回滾了。
而對於NESTED,雖然也會建立一個新事務,但是這個事務與呼叫者是有父子關係的相互依存的。
如果bMethod的傳播性是NESTED,而丟擲了一個異常,事務的回滾行為與REQUIRES_NEW是一致的。
但是如果aMethod在bMethod完成後出現了異常,bMethod同樣也會被回滾。因為事實上,EJB中沒有對於NESTED傳播性的類似實現,NESTED並不是真正啟動了一個事務,而是開啟了一個新的savepoint。
NEVER的含義很簡單,就是強制要求不在事務中執行,如果當前存在一個事務,則丟擲異常,因此如果bMethod傳播性是NEVER,則一定丟擲異常。
NOT_SUPPORTED的含義是,強制不在事務中執行,如果當前存在一個事務,則掛起該事務。
SUPPORTS的含義是,支援當前事務,如果沒有事務那麼就不在事務中執行。SUPPORTS傳播性的邏輯含義比較模糊,因此一般是不推薦使用的。
isolation引數—事務的隔離級別,Isolation型別(列舉),預設值為Isolation.DEFAULT,支援的值有DEFAULT、READ_COMMITTED、READ_UNCOMMITTED、REPEATABLE_READ、SERIALIZABLE。
timeout引數,int型別,事務的超時時間,預設值為-1,即不會超時。
readOnly引數,boolean型別,true表示事務為只讀,預設值為false。
rollbackFor引數,Class<? extends Throwable>[]型別,預設為空陣列。如果配置了以後,丟擲了指定異常或者其子類異常則回滾!
rollbackForClassName引數,String[]型別,預設為空陣列。
noRollbackFor引數,Class<? extends Throwable>[]型別,預設為空陣列。
noRollbackForClassName引數,String[]型別,預設為空陣列。
我配置的事務
Controller層
@RequestMapping(value = "updateemp",method = RequestMethod.PUT)
public ActionResult updateEmp(@RequestBody EmpQualification empQualification){
System.out.println("empQualification = " + empQualification);
try {
boolean result=empService.updateEmp(empQualification);
return new ActionResult(200,"update ok",null);
}catch (Exception e){
e.printStackTrace();
log.error("新增失敗,事務回滾");
}return new ActionResult(201,"update false", null);
}
Service層
@Transactional(propagation= Propagation.REQUIRED,isolation = Isolation.DEFAULT,rollbackFor=Exception.class)
@Override
public boolean updateEmp(EmpQualification empQualification) {
Integer i=empMapper.updateEmp(empQualification);
if(i!=0){
return true;
}else{
throw new RuntimeException("修改失敗,事務回滾");
}
}
dao層
Integer updateEmp(EmpQualification empQualification);
mapper語句
<update id="updateEmp" parameterType="com.yl.j2005.bean.sto.EmpQualification">
update emp set em_name=#{emName},
em_number=#{emNumber},
em_age=#{emAge},
em_sex=#{emSex},
em_birthday=#{emBirthday},
em_ethnic=#{emEthnic},
em_tel=#{emTel},
em_address=#{emAddress},
em_workspace=#{emWorkspace},
dept_id=#{deptId},
group_id=123456 where em_id=#{emId};
update qualification set em_biye=#{emBiye},em_congye=#{emCongye},em_shanggang#{emShanggang} where em_id=#{emId};
</update>
這裡要強調的是 如果一次執行多個語句,必須再資料庫連線字串url中新增如下配置
&allowMultiQueries=true
示例
spring.datasource.url=jdbc:mysql://192.168.0.109:3307/spcproject?allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false
//最後的&autoReconnect=true&failOverReadOnly=false是配置允許長時間未訪問資料庫的連線物件可訪問,不會被資料庫當成死連結
相關文章
- 初學事務管理:SpringBoot+MybatisSpring BootMyBatis
- Springboot事務失效原因Spring Boot
- springboot事務處理Spring Boot
- springboot-jta-atomikos多資料來源事務管理Spring Boot
- Spring的事務管理(二)宣告式事務管理Spring
- SpringBoot2 整合JTA元件,多資料來源事務管理Spring Boot元件
- Spring 事務管理Spring
- Springboot資料庫事務處理——Spring宣告式事務Spring Boot資料庫
- Spring系列.事務管理Spring
- Spring系列-事務管理Spring
- Spring的事務管理Spring
- springboot 事務建立流程原始碼分析Spring Boot原始碼
- springboot專案-宣告式事務失效Spring Boot
- Spring的事務管理入門:程式設計式事務管理(TransactionTemplate)Spring程式設計
- SpringBoot事務相關備忘(方法新增@Transactional註解,以及SQL語句(SQLServer資料庫)新增SET NOCOUNT ON)Spring BootSQLServer資料庫
- Spring 中的事務管理Spring
- Spring事務管理總結Spring
- SpringBoot2 基礎案例(12):基於轉賬案例,演示事務管理操作Spring Boot
- SpringBoot2-第三章:springboot的事務控制Spring Boot
- SpringBoot整合atomikos實現跨庫事務Spring Boot
- (四)Spring中的事務管理Spring
- golang的巢狀事務管理Golang巢狀
- spring宣告式事務管理配置Spring
- spring事務管理原始碼分析(二)事務處理流程分析Spring原始碼
- MyBatis 事務管理解析:顛覆你心中對事務的理解!MyBatis
- Spring的事務管理(一) Spring事務管理的實現,事務的屬性(隔離級別,傳播行為,只讀)Spring
- 使用Spring Boot實現事務管理Spring Boot
- Spring事務管理:非常規指南 - marcobehlerSpring
- 304441事務管理與併發控制
- Spring 程式設計式事務管理Spring程式設計
- mybaits原始碼分析--事務管理(八)AI原始碼
- Java多執行緒事務管理Java執行緒
- Spring事務管理(詳解+例項)Spring
- 分散式鎖和spring事務管理分散式Spring
- 微服務架構分散式事務管理問題微服務架構分散式
- Spring中事務管理org.springframework.transactionSpringFramework
- Spring框架中配置事務管理器Spring框架
- 編碼式事務管理使用例項