亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

springboot中手動提交事務(wù)的實(shí)現(xiàn)方法

 更新時(shí)間:2024年01月07日 10:00:31   作者:愛看老照片  
手動提交事務(wù)可以提供更靈活的控制,以便在分布式環(huán)境中處理事務(wù)的提交和回滾,本文就來介紹一下springboot中手動提交事務(wù)的實(shí)現(xiàn)方法,感興趣的可以了解一下

演示主要代碼

@Service 層代碼

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

@Service
@Transactional(rollbackFor = Exception.class)
public class XlServiceImpl {
	Logger logger = LoggerFactory.getLogger(this.getClass());
	@Autowired
	private XlMapper xlMapper;
	
	/**
	 * 需求:mi()方法拋出異常,不影響本方法:本方法不回滾!
	 * mi拋出異常后,insert1()正常插入
	 * @param id
	 * @return
	 * @throws Exception
	 */
	public String doInsert() throws Exception {
		xlMapper.insert1();
		mi();
		return "200";
	}
	
	/**
	 * 需求:本方法拋出異常時(shí),回滾
	 * 拋出異常后,insert2()回滾:不插入
	 */
	private void mi() {
		xlMapper.insert2();
		int x = 0;
		int y = 3 / x; // 
	}

}

Mapper接口層代碼: insert1()和insert2()的插入SQL

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Update;

public interface XlMapper {

    @Update("UPDATE xl999 SET age=333 WHERE id=#{id}")
	Integer updateById(Integer id);
    
    @Insert("INSERT INTO xl (name,age,create_time) VALUES('dp1',111,NOW())")
    Integer insert1();
    
    @Insert("INSERT INTO xl (name,age,create_time) VALUES('dp2',222,NOW())")
    Integer insert2();
}

controller層代碼

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ClassForTest {
	Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private XlServiceImpl xlServiceImpl;

	@GetMapping("/dosth")
	public String doSth() throws Exception {
		String affect = "";
		affect = xlServiceImpl.doInsert();
		return affect;
	}
}

數(shù)據(jù)庫表結(jié)構(gòu)及初始數(shù)據(jù)

在這里插入圖片描述

場景/需求/實(shí)際效果

場景
在spring的聲明式事務(wù)@Transactional(rollbackFor = Exception.class)的類XlServiceImpl中:

  • 有其中一個(gè)方法doInsert()調(diào)用另外一個(gè)方法mi()。
  • doInsert()會調(diào)用Mapper接口的insert1()方法向數(shù)據(jù)庫中插入一條數(shù)據(jù),然后會調(diào)用方法mi()。
  • mi()會調(diào)用Mapper接口的insert2()方法向數(shù)據(jù)庫中插入一條數(shù)據(jù),然后會拋出異常。

需求

insert1()可以正常插入,insert2()回滾,不會插入!

實(shí)際效果
運(yùn)行項(xiàng)目,調(diào)用方法,結(jié)果如下:

頁面:

在這里插入圖片描述

程序后臺

在這里插入圖片描述

數(shù)據(jù)庫: 與初始數(shù)據(jù)庫數(shù)據(jù)一致,并沒有數(shù)據(jù)插入——與需求中的 insert1()成功插入不符合。

在這里插入圖片描述

解決辦法 :在mi方法中手動提交事務(wù)

  • 在@Transactional(rollbackFor = Exception.class)類中注入spring的事務(wù)管理器PlatformTransactionManager:
	/**
	 * 引入 (平臺)事務(wù)管理器,Spring 事務(wù)策略的核心。
	 */
	@Autowired
	private PlatformTransactionManager transactionManager;
  • 在mi方法中手動提交事務(wù)/回滾事務(wù)
	/**
	 * 需求:本方法拋出異常時(shí),回滾 拋出異常后,insert2()回滾:不插入
	 */
	private void mi() {
		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);// 新發(fā)起一個(gè)事務(wù)
		TransactionStatus status = transactionManager.getTransaction(def);// 獲得事務(wù)狀態(tài)
		try {
			xlMapper.insert2();
			int x = 0;
			int y = 3 / x;
			// 手動提交事務(wù)
			transactionManager.commit(status);
		} catch (Exception e) {
			// 手動回滾事務(wù)
			transactionManager.rollback(status);
		}
	}

運(yùn)行項(xiàng)目,調(diào)用方法,查看效果:

在這里插入圖片描述

進(jìn)一步測試:注釋掉下面兩行,效果雖然是一樣的,但是,還是寫上最好??!

transactionManager.commit(status);
transactionManager.rollback(status);

mi()的完整代碼:

/**
	 * 需求:本方法拋出異常時(shí),回滾 拋出異常后,insert2()回滾:不插入
	 */
	private void mi() {
		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);// 新發(fā)起一個(gè)事務(wù)
		TransactionStatus status = transactionManager.getTransaction(def);// 獲得事務(wù)狀態(tài)
		try {
			xlMapper.insert2();
			int x = 0;
			int y = 3 / x;
			// 手動提交事務(wù)
//			transactionManager.commit(status);
		} catch (Exception e) {
			// 手動回滾事務(wù)
//			transactionManager.rollback(status);
		}
	}

以上說明:真正起作用的是下面3行:

		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);// 新發(fā)起一個(gè)事務(wù)
		TransactionStatus status = transactionManager.getTransaction(def);// 獲得事務(wù)狀態(tài)

而,這3行中又起關(guān)鍵作用的是最后一行 :

TransactionStatus status = transactionManager.getTransaction(def);// 獲得事務(wù)狀態(tài)

在這里插入圖片描述

通過第2句可知:最后一句是創(chuàng)建一個(gè)新事務(wù)!而這個(gè)新事務(wù)會自動完成提交和回滾,所以注釋掉 提交和回滾的代碼效果是一樣的?。√貏e注意:

  • @Transactional(rollbackFor = Exception.class) 方式創(chuàng)建的事務(wù),如果將異常catch后,在catch塊中不再拋出異常,是不會觸發(fā)回滾的!
  • 但是,在方法中顯示手動創(chuàng)建一個(gè)事務(wù):
		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);// 新發(fā)起一個(gè)事務(wù)
		TransactionStatus status = transactionManager.getTransaction(def);// 獲得事務(wù)狀態(tài)

這種手動方式創(chuàng)建的事務(wù),在catch塊中可以不用再拋出異常,也可以不用顯示的寫出:transactionManager.rollback(status); ,會自動進(jìn)行回滾!

在方法中手動創(chuàng)建事務(wù)時(shí),transactionManager.rollback(status); 最多只能執(zhí)行一次,如果方法中有2個(gè)及以上地方調(diào)用的transactionManager.rollback(status); 回滾方法,那么程序就會拋出異常!如下:

在這里插入圖片描述

在這里插入圖片描述

在方法中如果執(zhí)行了事務(wù)提交:transactionManager.commit(status); 后面再去執(zhí)行事務(wù)回滾transactionManager.rollback(status);,也會報(bào)上圖的錯(cuò)誤 “事務(wù)已完成——不要再同一個(gè)事務(wù)中提交或回滾超過一次”

也就是說,不管是提交事務(wù),還是回滾事務(wù),二者只能有一個(gè)執(zhí)行并且只能執(zhí)行一次?。。?/p>

在這里插入圖片描述

Spring的7中事務(wù)傳播行為

Propagation.REQUIRED代表當(dāng)前方法支持當(dāng)前的事務(wù),且與調(diào)用者處于同一事務(wù)上下文中,回滾統(tǒng)一回滾(如果當(dāng)前方法是被其他方法調(diào)用的時(shí)候,且調(diào)用者本身即有事務(wù)),如果沒有事務(wù),則自己新建事務(wù),
Propagation.SUPPORTS代表當(dāng)前方法支持當(dāng)前的事務(wù),且與調(diào)用者處于同一事務(wù)上下文中,回滾統(tǒng)一回滾(如果當(dāng)前方法是被其他方法調(diào)用的時(shí)候,且調(diào)用者本身即有事務(wù)),如果沒有事務(wù),則該方法在非事務(wù)的上下文中執(zhí)行
Propagation.MANDATORY代表當(dāng)前方法支持當(dāng)前的事務(wù),且與調(diào)用者處于同一事務(wù)上下文中,回滾統(tǒng)一回滾(如果當(dāng)前方法是被其他方法調(diào)用的時(shí)候,且調(diào)用者本身即有事務(wù)),如果沒有事務(wù),則拋出異常
Propagation.REQUIRES_NEW創(chuàng)建一個(gè)新的事務(wù)上下文,如果當(dāng)前方法的調(diào)用者已經(jīng)有了事務(wù),則掛起調(diào)用者的事務(wù),這兩個(gè)事務(wù)不處于同一上下文,如果各自發(fā)生異常,各自回滾
Propagation.NOT_SUPPORTED該方法以非事務(wù)的狀態(tài)執(zhí)行,如果調(diào)用該方法的調(diào)用者有事務(wù)則先掛起調(diào)用者的事務(wù)
Propagation.NEVER該方法以非事務(wù)的狀態(tài)執(zhí)行,如果調(diào)用者存在事務(wù),則拋出異常
Propagation.NESTED如果當(dāng)前上下文中存在事務(wù),則以嵌套事務(wù)執(zhí)行該方法,也就說,這部分方法是外部方法的一部分,調(diào)用者回滾,則該方法回滾,但如果該方法自己發(fā)生異常,則自己回滾,不會影響外部事務(wù),如果不存在事務(wù),則與PROPAGATION_REQUIRED一樣

在這里插入圖片描述

到此這篇關(guān)于springboot中手動提交事務(wù)的實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)springboot 手動提交事務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • Java 內(nèi)部類的定義與范例

    Java 內(nèi)部類的定義與范例

    說起內(nèi)部類這個(gè)詞,想必很多人都不陌生,但是又會覺得不熟悉。原因是平時(shí)編寫代碼時(shí)可能用到的場景不多,用得最多的是在有事件監(jiān)聽的情況下,并且即使用到也很少去總結(jié)內(nèi)部類的用法。今天我們就來一探究竟
    2021-11-11
  • Java中的NoSuchMethodException異常原因以及解決方案詳解

    Java中的NoSuchMethodException異常原因以及解決方案詳解

    這篇文章主要介紹了Java中的NoSuchMethodException異常原因以及解決方案詳解,NoSuchMethodException是Java反射機(jī)制中的異常,在嘗試通過反射獲取方法時(shí),找不到指定的方法,通常發(fā)生在調(diào)用?Class?對象的方法時(shí),當(dāng)方法名或方法參數(shù)不匹配時(shí)拋出該異常,需要的朋友可以參考下
    2024-02-02
  • Servlet文件的上傳與下載詳解

    Servlet文件的上傳與下載詳解

    很多朋友不清楚在Servlet中怎么上傳下載文件,談到這個(gè)問題,首先需要我們掌握開發(fā)servlet的步驟,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2022-06-06
  • springboot集成druid,多數(shù)據(jù)源可視化,p6spy問題

    springboot集成druid,多數(shù)據(jù)源可視化,p6spy問題

    這篇文章主要介紹了springboot集成druid,多數(shù)據(jù)源可視化,p6spy問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • SpringBoot?整合Redis?數(shù)據(jù)庫的方法

    SpringBoot?整合Redis?數(shù)據(jù)庫的方法

    Redis是一個(gè)基于內(nèi)存的日志型可持久化的緩存數(shù)據(jù)庫,保存形式為key-value格式,Redis完全免費(fèi)開源,它使用ANSI?C語言編寫。這篇文章主要介紹了SpringBoot?整合Redis?數(shù)據(jù)庫的方法,需要的朋友可以參考下
    2018-03-03
  • 實(shí)例講解java定時(shí)任務(wù)

    實(shí)例講解java定時(shí)任務(wù)

    這篇文章主要介紹了實(shí)例講解java定時(shí)任務(wù),感興趣的的朋友可以參考下
    2015-08-08
  • jvm支持最大線程數(shù)簡單測試

    jvm支持最大線程數(shù)簡單測試

    這篇文章主要介紹了jvm支持最大線程數(shù)簡單測試,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • idea?2024使用Maven創(chuàng)建Java?Web項(xiàng)目詳細(xì)圖文教程

    idea?2024使用Maven創(chuàng)建Java?Web項(xiàng)目詳細(xì)圖文教程

    這篇文章主要給大家介紹了關(guān)于idea?2024使用Maven創(chuàng)建Java?Web項(xiàng)目的相關(guān)資料,介紹了如何使用Maven創(chuàng)建一個(gè)Spring?MVC項(xiàng)目,并配置Tomcat服務(wù)器以運(yùn)行一個(gè)簡單的Helloworld?JSP頁面,需要的朋友可以參考下
    2024-12-12
  • java中用ObjectMapper類實(shí)現(xiàn)Json與bean的轉(zhuǎn)換示例

    java中用ObjectMapper類實(shí)現(xiàn)Json與bean的轉(zhuǎn)換示例

    這篇文章主要給大家介紹了關(guān)于在java中用ObjectMapper類實(shí)現(xiàn)Json與bean轉(zhuǎn)換的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • SpringSecurity獲取當(dāng)前登錄用戶的信息的幾種方法實(shí)現(xiàn)

    SpringSecurity獲取當(dāng)前登錄用戶的信息的幾種方法實(shí)現(xiàn)

    本文主要介紹了SpringSecurity中獲取當(dāng)前登錄用戶信息的多種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03

最新評論