欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot中的事務(wù)處理問題

 更新時(shí)間:2024年01月12日 10:18:40   作者:龍域、白澤  
這篇文章主要介紹了SpringBoot中的事務(wù)處理問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

介紹

在實(shí)際的業(yè)務(wù)場(chǎng)景中,不光數(shù)據(jù)庫要實(shí)現(xiàn)事務(wù),我們的Service層業(yè)務(wù)也要實(shí)現(xiàn)事務(wù)。

例如:要實(shí)現(xiàn)數(shù)據(jù)的刪除,刪除數(shù)據(jù)庫中的數(shù)據(jù)并刪除Redis緩存中的數(shù)據(jù),他們?cè)谝粋€(gè)ServiceImpl的方法中,我們要實(shí)現(xiàn)這兩個(gè)操作放在一個(gè)事務(wù)中,兩個(gè)操作同時(shí)成功 / 失敗,所有,要使用Spring事務(wù)。

SpringBoot中事務(wù)實(shí)現(xiàn)

ServiceImpl的方法 / ServiceImpl類 上加上@Transactional。

  • 方法:注解只對(duì)public方法有效(因?yàn)锧Transactional 工作原理是基于AOP實(shí)現(xiàn)的),如果在 protected、private 或者默認(rèn)方法上使用,沒有作用,也不報(bào)錯(cuò)。
  • 類:該類的所有 public 方法將都具有該類型的事務(wù)屬性

注意:在方法級(jí)別使用該注解可以覆蓋類級(jí)別使用該注解。

// 這個(gè)類中的public方法如果拋出Exception,則該方法會(huì)回滾
@Transactional(rollbackFor = Exception.class)
public class DefaultFooService implements FooService {
 
  public Foo getFoo(String fooName) {
    // do something
  }
 
  // these settings have precedence for this method
  //方法上注解屬性會(huì)覆蓋類注解上的相同屬性
  @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
  public void updateFoo(Foo foo) {
    // do something
  }
}

@EnableTransactionManagement

SpringBoot啟動(dòng)類上加上不用加@EnableTransactionManagement注解,SpringBoot自動(dòng)裝配已經(jīng)幫我們處理了,SpringBoot項(xiàng)目默認(rèn)支持事務(wù)。

@Transactional

作用位置:接口、接口方法、類以及類方法

Spring 建議不要在接口或者接口方法上使用該注解,因?yàn)檫@只有在使用基于接口的代理時(shí)它才會(huì)生效。

注意:

默認(rèn)情況下,只有來自外部的方法調(diào)用才會(huì)被AOP代理捕獲,也就是,類內(nèi)部方法調(diào)用本類內(nèi)部的其他方法并不會(huì)引起事務(wù)行為,即使被調(diào)用方法使用@Transactional注解進(jìn)行修飾。

Transactional類

package org.springframework.transaction.annotation;
 
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
import org.springframework.core.annotation.AliasFor;
import org.springframework.transaction.TransactionDefinition;
 
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
 
	@AliasFor("transactionManager")
	String value() default "";
 
	@AliasFor("value")
	String transactionManager() default "";
 
	Propagation propagation() default Propagation.REQUIRED;
 
	Isolation isolation() default Isolation.DEFAULT;
 
	int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
 
	boolean readOnly() default false;
 
	Class<? extends Throwable>[] rollbackFor() default {};
 
	String[] rollbackForClassName() default {};
 
	Class<? extends Throwable>[] noRollbackFor() default {};
 
	String[] noRollbackForClassName() default {};
}

注解的屬性

屬性類型描述
valueString可選的限定描述符,指定使用的事務(wù)管理器
propagationenum: Propagation可選的事務(wù)傳播行為設(shè)置
isolationenum: Isolation可選的事務(wù)隔離級(jí)別設(shè)置
readOnlyboolean讀寫或只讀事務(wù),默認(rèn)讀寫
timeoutint (in seconds granularity)事務(wù)超時(shí)時(shí)間設(shè)置
rollbackForClass對(duì)象數(shù)組,必須繼承自Throwable導(dǎo)致事務(wù)回滾的異常類數(shù)組
rollbackForClassName類名數(shù)組,必須繼承自Throwable導(dǎo)致事務(wù)回滾的異常類名字?jǐn)?shù)組
noRollbackForClass對(duì)象數(shù)組,必須繼承自Throwable不會(huì)導(dǎo)致事務(wù)回滾的異常類數(shù)組
noRollbackForClassName類名數(shù)組,必須繼承自Throwable不會(huì)導(dǎo)致事務(wù)回滾的異常類名字?jǐn)?shù)組

在Spring中定義了五種隔離級(jí)別常量

一般用默認(rèn)就可以。

package org.springframework.transaction.annotation;
 
import org.springframework.transaction.TransactionDefinition;
 
public enum Isolation {
 
	DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),
 
	READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),
 
	READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED),
 
	REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ),
	
	SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);
 
 
	private final int value;
 
	Isolation(int value) {
		this.value = value;
	}
 
	public int value() {
		return this.value;
	}
}
常量說明
TransactionDefinition.ISOLATION_DEFAULT數(shù)據(jù)庫默認(rèn)的隔離級(jí)別,MySQL默認(rèn)采用的 REPEATABLE_READ隔離級(jí)別
TransactionDefinition.ISOLATION_READ_UNCOMMITTED最低的隔離級(jí)別,允許讀取未提交的數(shù)據(jù)變更,可能會(huì)導(dǎo)致臟讀、幻讀或不可重復(fù)讀。
TransactionDefinition.ISOLATION_READ_COMMITTED允許讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù),可以阻止臟讀,但是幻讀或不可重復(fù)讀仍有可能發(fā)生。
TransactionDefinition.ISOLATION_REPEATABLE_READ對(duì)同一字段的多次讀取結(jié)果都是一致的,除非數(shù)據(jù)是被本身事務(wù)自己所修改,可以阻止臟讀和不可重復(fù)讀,但幻讀仍有可能發(fā)生。MySQL中通過MVCC解決了該隔離級(jí)別下出現(xiàn)幻讀的可能。
TransactionDefinition.ISOLATION_SERIALIZABLE串行化隔離級(jí)別,該級(jí)別可以防止臟讀、不可重復(fù)讀以及幻讀,但是串行化會(huì)影響性能。

Spring定義了七種事務(wù)傳播行為

類型說明
PROPAGATION_REQUIRED如果當(dāng)前沒有事務(wù),就新建一個(gè)事務(wù),如果已經(jīng)存在一個(gè)事務(wù)中,加入到這個(gè)事務(wù)中。這是最常見的選擇
PROPAGATION_SUPPORTS支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就以非事務(wù)方式執(zhí)行。
PROPAGATION_MANDATORY使用當(dāng)前的事務(wù),如果當(dāng)前沒有事務(wù),就拋出異常。
PROPAGATION_REQUIRES_NEW新建事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起。
PROPAGATION_NOT_SUPPORTED以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。
PROPAGATION_NEVER以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常。
PROPAGATION_NESTED如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒有事務(wù),則執(zhí)行與PROPAGATION_REQUIRED類似的操作。

Spring事務(wù)什么情況下會(huì)失效

【1】@Transactional 應(yīng)用在非 public 修飾的方法上

@Transactional 工作原理是基于AOP實(shí)現(xiàn)的

所以,注解必須作用在public的方法上,否則失效。

【2】數(shù)據(jù)庫引擎是否支持事務(wù)(MySql的MyIsam引擎不支持事物)

【3】@Transactional注解屬性 propagation 設(shè)置錯(cuò)誤

  • TransactionDefinition.PROPAGATION_SUPPORTS:如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則以非事務(wù)的方式繼續(xù)運(yùn)行。
  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。
  • TransactionDefinition.PROPAGATION_NEVER:以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則拋出異。

【4】@Transactional 注解屬性 rollbackFor 設(shè)置錯(cuò)誤?       

  • Spring默認(rèn)是回滾RuntimeException才回滾。
  • 當(dāng)然自定義的RuntimeException異常類也是可以的。
  • 如果希望Spring能夠回滾別類型的異常,那就需要使用rollbackFor去指定(當(dāng)然如果是指定異常的子類,也同樣會(huì)回滾)。

【5】同一個(gè)類中方法調(diào)用,導(dǎo)致@Transactional失效?       

在同一個(gè)類中,沒有加事務(wù)的方法A調(diào)用加事務(wù)的方法B,方法B的事務(wù)失效。

( 其實(shí)這還是由于使用Spring AOP代理造成的),所以:建議把整個(gè)類加上事務(wù)注解。

【6】異常被捕獲了?        

這個(gè)就比較簡(jiǎn)單了,就是你自己捕捉到了異常,并且自己處理,并不會(huì)拋出到上層的方法調(diào)用。

那就不會(huì)生效了。

@Transactional
public void contextLoads() {
    try {
        int i = 0;
    }catch (Exception e){
        System.out.println("不可以回滾");
    }
}

可以手動(dòng)設(shè)置回滾

@Transactional
public void contextLoads() {
    try {
        int i = 0;
    }catch (Exception e){
        // 手動(dòng)回滾
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        System.out.println("可以回滾");
    }
}

【7】新開啟一個(gè)線程        

Spring實(shí)現(xiàn)事務(wù)的原理是通過ThreadLocal把數(shù)據(jù)庫連接綁定到當(dāng)前線程中,新開啟一個(gè)線程獲取到的連接就不是同一個(gè)了。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 將Arthas整合到Java業(yè)務(wù)鏡像中的流程步驟

    將Arthas整合到Java業(yè)務(wù)鏡像中的流程步驟

    在現(xiàn)代Java應(yīng)用開發(fā)中,診斷和調(diào)試是一個(gè)不可或缺的環(huán)節(jié),Arthas,作為阿里巴巴開源的一款Java診斷工具,提供了一種在不修改代碼的情況下,實(shí)時(shí)監(jiān)控、診斷和調(diào)試Java應(yīng)用程序的解決方案,本文將詳細(xì)介紹Arthas的基本概念,并逐步指導(dǎo)如何將其整合到Java業(yè)務(wù)鏡像中
    2025-02-02
  • Java超詳細(xì)教你寫一個(gè)銀行存款系統(tǒng)案例

    Java超詳細(xì)教你寫一個(gè)銀行存款系統(tǒng)案例

    這篇文章主要介紹了怎么用Java來寫一個(gè)銀行的存款系統(tǒng),銀行存款主要有賬號(hào)和存款金額兩個(gè)屬性,感興趣的朋友跟隨文章往下看看吧
    2022-03-03
  • java更改圖片大小示例分享

    java更改圖片大小示例分享

    這篇文章主要介紹了java更改圖片大小示例,方法中指定路徑 ,舊文件名稱 ,新文件名稱,n 改變倍數(shù)就可以完成更改圖片大小,需要的朋友可以參考下
    2014-03-03
  • 快速理解Java設(shè)計(jì)模式中的組合模式

    快速理解Java設(shè)計(jì)模式中的組合模式

    這篇文章主要介紹了快速理解Java設(shè)計(jì)模式中的組合模式,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • 使用開源項(xiàng)目JAVAE2 進(jìn)行視頻格式轉(zhuǎn)換

    使用開源項(xiàng)目JAVAE2 進(jìn)行視頻格式轉(zhuǎn)換

    這篇文章主要介紹了使用開源項(xiàng)目JAVAE 進(jìn)行視頻格式轉(zhuǎn)換,幫助大家更好的利用Java處理視頻,完成自身需求,感興趣的朋友可以了解下
    2020-11-11
  • Java Session驗(yàn)證碼案例代碼實(shí)例解析

    Java Session驗(yàn)證碼案例代碼實(shí)例解析

    這篇文章主要介紹了Java Session驗(yàn)證碼案例代碼實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • SpringBoot?啟動(dòng)流程追蹤方法分享

    SpringBoot?啟動(dòng)流程追蹤方法分享

    這篇文章主要介紹了SpringBoot?啟動(dòng)流程追蹤方法分享的相關(guān)資料,需要的朋友可以參考下
    2023-08-08
  • Java中List根據(jù)條件刪除元素的幾種方式

    Java中List根據(jù)條件刪除元素的幾種方式

    java List刪除指定元素有四種方法,分別是普通for循環(huán),增強(qiáng)for循環(huán),CopyOnWriteArrayList以及原生的Iterator迭代器循環(huán)來刪除list中指定的某個(gè)元素,非常的簡(jiǎn)單,并通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下
    2024-04-04
  • java實(shí)現(xiàn)將ftp和http的文件直接傳送到hdfs

    java實(shí)現(xiàn)將ftp和http的文件直接傳送到hdfs

    前面幾篇文章,我們已經(jīng)做了很好的鋪墊了,幾個(gè)要用到的工具我們都做了出來,本文就是將他們集合起來,說下具體的用法,小伙伴們可以參考下。
    2015-03-03
  • myeclipse開發(fā)servlet_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    myeclipse開發(fā)servlet_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    MyEclipse,是在eclipse基礎(chǔ)上加上自己的插件開發(fā)而成的功能強(qiáng)大的企業(yè)級(jí)集成開發(fā)環(huán)境,主要用于Java、Java EE以及移動(dòng)應(yīng)用的開發(fā)。下面這篇文章主要給大家介紹了關(guān)于myeclipse開發(fā)servlet的相關(guān)資料,需要的朋友可以參考下。
    2017-07-07

最新評(píng)論