最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2024年01月07日 10:00:31   作者:愛看老照片  
手動(dòng)提交事務(wù)可以提供更靈活的控制,以便在分布式環(huán)境中處理事務(wù)的提交和回滾,本文就來介紹一下springboot中手動(dòng)提交事務(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ù)

在這里插入圖片描述

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

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

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

需求

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

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

頁面:

在這里插入圖片描述

程序后臺(tái)

在這里插入圖片描述

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

在這里插入圖片描述

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

  • 在@Transactional(rollbackFor = Exception.class)類中注入spring的事務(wù)管理器PlatformTransactionManager:
	/**
	 * 引入 (平臺(tái))事務(wù)管理器,Spring 事務(wù)策略的核心。
	 */
	@Autowired
	private PlatformTransactionManager transactionManager;
  • 在mi方法中手動(dòng)提交事務(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;
			// 手動(dòng)提交事務(wù)
			transactionManager.commit(status);
		} catch (Exception e) {
			// 手動(dòng)回滾事務(wù)
			transactionManager.rollback(status);
		}
	}

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

在這里插入圖片描述

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

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;
			// 手動(dòng)提交事務(wù)
//			transactionManager.commit(status);
		} catch (Exception e) {
			// 手動(dòng)回滾事務(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ù)會(huì)自動(dòng)完成提交和回滾,所以注釋掉 提交和回滾的代碼效果是一樣的!!特別注意:

  • @Transactional(rollbackFor = Exception.class) 方式創(chuàng)建的事務(wù),如果將異常catch后,在catch塊中不再拋出異常,是不會(huì)觸發(fā)回滾的!
  • 但是,在方法中顯示手動(dòng)創(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)

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

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

在這里插入圖片描述

在這里插入圖片描述

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

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

在這里插入圖片描述

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ā)生異常,則自己回滾,不會(huì)影響外部事務(wù),如果不存在事務(wù),則與PROPAGATION_REQUIRED一樣

在這里插入圖片描述

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

相關(guān)文章

  • java使用緩沖流復(fù)制文件的方法

    java使用緩沖流復(fù)制文件的方法

    這篇文章主要為大家詳細(xì)介紹了java使用緩沖流復(fù)制文件的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Java比較兩個(gè)對(duì)象大小的三種方法詳解

    Java比較兩個(gè)對(duì)象大小的三種方法詳解

    在優(yōu)先級(jí)隊(duì)列中插入的元素必須能比較大小,如果不能比較大小,如插入兩個(gè)學(xué)生類型的元素,會(huì)報(bào)ClassCastException異常。本文就為大家總結(jié)了Java比較兩個(gè)對(duì)象大小的三種方法,需要的可以參考一下
    2022-07-07
  • Spring5+SpringMvc+Hibernate5整合的實(shí)現(xiàn)

    Spring5+SpringMvc+Hibernate5整合的實(shí)現(xiàn)

    這篇文章主要介紹了Spring5+SpringMvc+Hibernate5整合的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • springboot如何集成Swagger2

    springboot如何集成Swagger2

    這篇文章主要介紹了springboot集成Swagger2的方法,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-12-12
  • 深入了解JAVA Jersey框架

    深入了解JAVA Jersey框架

    這篇文章主要介紹了JAVA Jersey的概念以及使用方法,文中講解非常詳細(xì),對(duì)大家的學(xué)習(xí)工作有所幫助,感興趣的朋友可以參考下
    2020-06-06
  • Java多線程正確使用倒計(jì)時(shí)協(xié)調(diào)器CountDownLatch方法詳解

    Java多線程正確使用倒計(jì)時(shí)協(xié)調(diào)器CountDownLatch方法詳解

    這篇文章主要為大家介紹了Java多線程倒計(jì)時(shí)協(xié)調(diào)器CountDownLatch的正確使用方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Java中遍歷Map的多種方法示例及優(yōu)缺點(diǎn)總結(jié)

    Java中遍歷Map的多種方法示例及優(yōu)缺點(diǎn)總結(jié)

    在java中遍歷Map有不少的方法,下面這篇文章主要給大家介紹了關(guān)于Java中遍歷Map的多種方法,以及各種方法的優(yōu)缺點(diǎn)總結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-07-07
  • Spring?Security自定義登錄頁面認(rèn)證過程常用配置

    Spring?Security自定義登錄頁面認(rèn)證過程常用配置

    這篇文章主要為大家介紹了Spring?Security自定義登錄頁面認(rèn)證過程常用配置示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Java中注解與元數(shù)據(jù)示例詳解

    Java中注解與元數(shù)據(jù)示例詳解

    Java注解和元數(shù)據(jù)是編程中重要的概念,用于描述程序元素的屬性和用途,這篇文章主要介紹了Java中注解與元數(shù)據(jù)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-01-01
  • java實(shí)現(xiàn)后臺(tái)返回base64圖形編碼

    java實(shí)現(xiàn)后臺(tái)返回base64圖形編碼

    這篇文章主要介紹了java實(shí)現(xiàn)后臺(tái)返回base64圖形編碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06

最新評(píng)論

乌拉特后旗| 乌海市| 陆河县| 唐海县| 西平县| 金乡县| 白朗县| 镇康县| 丹江口市| 阳谷县| 南和县| 历史| 北辰区| 屯昌县| 泰顺县| 宜宾县| 安庆市| 资阳市| 海兴县| 将乐县| 晴隆县| 平山县| 二手房| 杭州市| 吴川市| 墨脱县| 鹤峰县| 西安市| 镇沅| 兰坪| 宣武区| 南阳市| 盐亭县| 宾川县| 泽普县| 西和县| 上林县| 襄樊市| 册亨县| 富民县| 冀州市|