spring之事務回滾技巧

2020-12-11 幽默工場

作者:WhyWin出處:cnblogs.com/0201zcr/p/5962578.html

知音專欄

關於資源視頻下載的說明

常用設計模式完整系列篇

【強化編程功底】算法文摘

1、遇到的問題

當我們一個方法裡面有多個資料庫保存操作的時候,中間的資料庫操作發生的錯誤。偽代碼如下:

publicmethod() {Dao1.save(Person1);Dao1.save(Person2);Dao1.save(Person2);//假如這句發生了錯誤,前面的兩個對象會被保存到資料庫中Dao1.save(Person2);}

期待的情況:發生錯誤之前的所有資料庫保存操作都回滾,即不保存

正常情況:前面的資料庫操作會被執行,而發生資料庫操作錯誤開始及之後的所有的數據保存操作都將失敗。這樣子應該都不是我們要的結果吧。

當遇到這種情況,我們就可以使用Spring的事務解決這個問題。

2、異常的一些基本知識

1) 異常的架構

Throwable為基類,Error和Exception繼承Throwable,RuntimeException和IOException等繼承Exception。

Error和RuntimeException及其子類成為未檢查異常(unchecked),其它異常成為已檢查異常(checked)。

2)Error異常

Error表示程序在運行期間出現了十分嚴重、不可恢復的錯誤,在這種情況下應用程式只能中止運行,例如JAVA 虛擬機出現錯誤。Error是一種unchecked Exception,編譯器不會檢查Error是否被處理,在程序中不用捕獲Error類型的異常。一般情況下,在程序中也不應該拋出Error類型的異常。

3)RuntimeException異常

Exception異常包括RuntimeException異常和其他非RuntimeException的異常。

RuntimeException 是一種Unchecked Exception,即表示編譯器不會檢查程序是否對RuntimeException作了處理,在程序中不必捕獲RuntimException類型的異常,也不必在方法體聲明拋出RuntimeException類。

RuntimeException發生的時候,表示程序中出現了編程錯誤,所以應該找出錯誤修改程序,而不是去捕獲RuntimeException。

4)Checked Exception異常

Checked Exception異常,這也是在編程中使用最多的Exception,所有繼承自Exception並且不是RuntimeException的異常都是checked Exception,上圖中的IOException和ClassNotFoundException。

JAVA 語言規定必須對checked Exception作處理,編譯器會對此作檢查,要麼在方法體中聲明拋出checked Exception,要麼使用catch語句捕獲checked Exception進行處理,不然不能通過編譯。

3、實例

這裡使用的事務配置如下:

<!-- Jpa 事務配置 --><beanid="transactionManager"class="org.springframework.orm.jpa.JpaTransactionManager"><propertyname="entityManagerFactory"ref="entityManagerFactory"/></bean><!-- 開啟註解事務 --><tx:annotation-driventransaction-manager="transactionManager"proxy-target-class="true" />

在spring的配置文件中,如果數據源的defaultAutoCommit設置為True了,那麼方法中如果自己捕獲了異常,事務是不會回滾的,如果沒有自己捕獲異常則事務會回滾,如下例

比如配置文件裡有這麼條記錄

<bean id="dataSource"class="com.alibaba.druid.pool.DruidDataSource"> <property name="xxx"value="xxx"/> <property name="xxx"value="xxx"/> .... <property name="defaultAutoCommit"value="true" /> </bean>

可能你會發現你並沒有配置這個參數,是不是他就不會自動提交呢?答案是不是的,我這裡是使用了com.alibaba.druid.pool.DruidDataSource作為資料庫連接池,默認的defaultAutoCommit就是true,可以看下面的源碼

那麼現在有兩個情況

情況1:如果沒有在程序中手動捕獲異常

@Transactional(rollbackOn = { Exception.class }) publicvoidtest()throws Exception { doDbStuff1(); doDbStuff2();//假如這個操作資料庫的方法會拋出異常,//現在方法doDbStuff1()對資料庫的操作 會回滾。 }

情況2:如果在程序中自己捕獲了異常

@Transactional(rollbackOn = { Exception.class }) publicvoidtest(){ try { doDbStuff1(); doDbStuff2();//假如這個操作資料庫的方法會拋出異常,//現在方法doDbStuff1()對資料庫的操作 不會回滾。 } catch (Exception e) { e.printStackTrace(); } }

現在如果我們需要手動捕獲異常,並且也希望拋異常的時候能回滾腫麼辦呢?

下面這樣寫就好了,手動回滾事務:

@Transactional(rollbackOn = { Exception.class }) public void test() { try { doDbStuff1(); doDbStuff2(); } catch (Exception e) { e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//就是這一句了,加上之後,如果doDbStuff2()拋了異常,//doDbStuff1()是會回滾的 } }

送書活動欄

RxJava2.x實戰

相關焦點

  • Spring事務基礎
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">    <!* -EXCEPTION :發生哪些異常回滾事務                        * +EXCEPTION :發生哪些異常不回滾事務                 -->                <prop key="transfer">PROPAGATION_REQUIRED,readOnly</prop>
  • Spring事務管理
    Timeout超時對事務執行的時長設置一個閥值,如果超過閥值還未完成則回滾。4. Propagation傳播行為當一個方法開啟事務後,在方法中調用了其他的方法,其他方法可能也需要事務管理,此時就涉及事務該如何傳播了。4.1.
  • Spring的編程式事務和聲明式事務詳解
    tx標籤配置的攔截器:基於tx和aop名字空間的xml配置文件(基於Aspectj AOP配置事務);全註解:基於@Transactional註解;Spring事務特性Spring所有的事務管理策略類都繼承自org.springframework.transaction.PlatformTransactionManager接口,用於執行具體的事務操作。
  • 這可能是對 Spring 事務原理講解最透徹的文章了
    接下來我們通過分析一些嵌套事務的場景,來深入理解spring事務傳播的機制。() 的事務級別定義為 PROPAGATION_REQUIRED,那麼執行 ServiceA.methodA() 的時候spring已經起了事務,這時調用 ServiceB.methodB(),ServiceB.methodB() 看到自己已經運行在 ServiceA.methodA() 的事務內部,就不再起新的事務。
  • Spring的@Transactional註解詳細用法
    API如JTA更簡單的編程式事務管理API與spring數據訪問抽象的完美集成事務管理方式spring支持編程式事務管理和聲明式事務管理兩種方式。編程式事務管理使用TransactionTemplate或者直接使用底層的PlatformTransactionManager。對於編程式事務管理,spring推薦使用TransactionTemplate。聲明式事務管理建立在AOP之上的。其本質是對方法前後進行攔截,然後在目標方法開始之前創建或者加入一個事務,在執行完目標方法之後根據執行情況提交或者回滾事務。
  • Redis事務詳解,Redis事務不支持回滾嗎?
    Redis事務提供2個重要保證MULTI, EXEC, DISCARD 和WATCH命令是Redis事務操作的基礎 。所有的命令要麼都被一起處理,要麼全都沒有被處理,所以Redis事務是原子的。EXEC會命令觸發事務中所有命令的執行。當正在使用AOF時,Redis會使用一個簡單的write(2)系統級調用來確保把事務寫入到磁碟。但是,如果Redis服務崩潰,或者被系統管理員以某種強制的方式殺死,那麼可能只有部分命令被寫入到磁碟。
  • 寶貝,來,講講 Spring 事務有哪些坑?
    Spring 什麼情況下進行事務回滾首先我們要明白, Spring 事務回滾機制是這樣的:當所攔截的方法有指定異常拋出,事務才會自動進行回滾!還有就是,默認配置下,事務只會對 Error 與 RuntimeException 及其子類這些異常做出回滾。一般的 Exception 這些 Checked 異常不會發生回滾。
  • 在實際開發中對數據流的處理,和事務處理中遇到的坑,及解決方案
    ThrowableSpring框架的事務基礎架構代碼,默認地在運行時和unchecked exceptions時,才進行事務回滾,Errors 同樣默認地也進行事務回滾。1、讓checked例外也回滾:在整個方法前加上2、讓unchecked例外不回滾(估計這個沒人做)3、不需要事務管理的(只查詢的)方法:注意: 如果異常被
  • 使用Spring框架實現資料庫事務處理
    若利用資料庫事務技術執行上述操作,當發生上述情況時,資料庫系統會將先前執行的SQL語句撤銷,將資料庫回滾到事務執行前狀態。(4)丟失更新:當事務A和事務B對同一數據進行修改時,就會發生丟失更新的問題。例如,B事務對m記錄進行了修改,A事務在修改m記錄時發生異常並回滾,就會將B事務對m記錄的修改覆蓋掉。為了解決上面提到的事務並發問題,JDBC定義了五種事務隔離級別來解決來解決這些並發導致的問題。
  • 微服務 SpringCloud Alibaba Seata處理分布式事務
    TC (Transaction Coordinator) - 事務協調者維護全局和分支事務的狀態,驅動全局事務提交或回滾。可以理解為seata-server那個服務TM (Transaction Manager) - 事務管理器定義全局事務的範圍:開始全局事務、提交或回滾全局事務。可以理解為事務的發起者帶有@GlobalTransactional的服務。
  • 上盤硬菜,@Transaction源碼深度解析 | Spring系列第48篇
    大家好,今天咱們通過源碼來了解一下spring中@Transaction事務的原理。1、環境2、@Transaction 事務的用法咱們先來回顧一下,@Transaction 事務的用法,特別簡單,2個步驟1、在需要讓spring管理事務的方法上添加 @Transaction 註解2、在spring
  • 一文帶你看懂Spring事務!
    ,解決線程安全有很多方式,但其中有一種:讓每一個線程都擁有自己的一個變量:ThreadLocal二、兩個不靠譜直覺的例子2.1第一個例子 之前朋友問了我一個例子:在Service層拋出Exception,在Controller層捕獲,那如果在Service中有異常,那會事務回滾嗎?
  • 淺談事務管理器的事務恢復處理方案
    該模型是基於假定回滾的策略恢復失敗的事務。假定回滾是事務二階段提交協議的一種效率優化策略,事務發起者在決定提交之前和資源在準備好之前都不用寫任何日誌。這樣在失敗發生後重新啟動時,所有未記錄日誌的事務都認為已經做過回滾操作。ACID,指資料庫事務正確執行的四個基本要素的縮寫。
  • Spring事務實現原理
    事務的管理是受限於具體的數據源的(例如,JDBC對應的事務管理器就是DatasourceTransactionManager),因此PlatformTransactionManager只規定了事務的基本操作:創建事務,提交事物和回滾事務。
  • 一文輕鬆搞定批處理框架 Spring Batch
    Spring Batch 不僅提供了統一的讀寫接口、豐富的任務處理方式、靈活的事務管理及並發處理,同時還支持日誌、監控、任務重啟與跳過等特性,大大簡化了批處理應用開發,將開發人員從複雜的任務配置管理過程中解放出來,使他們可以更多地去關注核心的業務處理過程。  另外我們還需要知道,Spring Batch 是一款批處理應用框架,不是調度框架。
  • Java面試題事務是什麼 SpringAOP對事務管理
    spring概念Spring中的spring-tx包包含了Spring對事務管理的支持。我發現如果在Spring環境下,Spring是不能完成@autowied和@Resourece注入的,不知道是什麼原因,我們需要在導入一個包spring-test。如果在Tommcat環境下Spring就能說夠進行註解注入是不是Spring的註解依賴Tommcat下的某些東西或者是Jstl之類的東西呢?或是另一種可能我們執行Java代碼時,Spring容器沒有完成初始化所以不能注入。
  • 面試官:談談你對MySQL事務的認識?
    5、你有遇到過資料庫宕機重啟,事務丟失的情況麼?6、可重複讀是怎麼實現的?再三強調,每個問題都仔細看!都是高頻題!切勿遺漏!正文1、講講為什麼用事務?事務的四大特性?事務的隔離級別知道吧,你們生產用哪種?回答:為什麼用事務?
  • 那些讓你愛不釋手的 Spring 代碼技巧
    spring事務要如何避坑?spring中的事務功能主要分為:聲明式事務和編程式事務。聲明式事務大多數情況下,我們在開發過程中使用更多的可能是聲明式事務,即使用@Transactional註解定義的事務,因為它用起來更簡單,方便。
  • SpringBoot+ Dubbo + Mybatis + Nacos +Seata整合來實現Dubbo分布式事務
    ,全局回滾功能//        if (!5.2 測試回滾我們samples-business將BusinessServiceImpl的handleBusiness2 下面的代碼去掉注釋if (!flag) {  throw new RuntimeException("測試拋異常後,分布式事務回滾!")
  • Spring Boot 單元測試
    單元測試引用:眾所周知,通過spring initialize創建的Spring Boot項目會在Maven中自動攜帶很多starter依賴:其中包含了一個名為spring-boot-starter-test的依賴,本文是圍繞這個依賴展開。