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

Spring事務(wù)失效場(chǎng)景原理及解決方案

 更新時(shí)間:2020年09月27日 10:13:36   作者:愛(ài)笑的berg  
這篇文章主要介紹了Spring事務(wù)失效場(chǎng)景原理及解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

1.事務(wù)失效-自身調(diào)用(通過(guò)REQUIRES、REQUIRES_NEW傳播屬性):自身調(diào)用即調(diào)該類(lèi)自己的方法。

同類(lèi)OrderServiceImpl 中 doSomeThing()方法 不存在事務(wù),該方法去調(diào)用本類(lèi)中的存在事務(wù)注解的 insertAndUpdateOrderInfo() 方法。但是insertAndUpdateOrderInfo() 其實(shí)是無(wú)法保證預(yù)想的事務(wù)性。

示列驗(yàn)證:

OrderServiceImpl.insertAndUpdateOrderInfo方法中upateData(updateParam) 發(fā)生異常時(shí),insertData(insertParam) 未發(fā)生回滾
說(shuō)明:自身調(diào)用時(shí)候,無(wú)論是以下哪種傳播屬性均是無(wú)效的,因?yàn)樽陨碚{(diào)用時(shí)的子方法壓根就不會(huì)被AOP 代理攔截到以下的這兩種方式均經(jīng)過(guò)驗(yàn)證,無(wú)法保證子方法事務(wù)的有效性

@Transactional(propagation = Propagation.REQUIRES)
@Transactional(propagation = Propagation.REQUIRES_NEW)

@Controller
@RequestMapping("/trans")
public class TransactionalController {

  @Autowired
  OrderService orderService;

  @RequestMapping("/test.do")
  @ResponseBody
  public void getIndex(HttpServletRequest request, HttpServletResponse response, Model model) {

    orderService.doSomeThing();

  }

}

@Service
public interface OrderService {

  /*
  *添加訂單和修改其他訂單信息
  * */
  public void doSomeThing();

}



@Service
public class OrderServiceImpl implements OrderService {
  @Autowired
  TransBusiness transBusiness;

  @Override
  public void doSomeThing() {

    insertAndUpdateOrderInfo();

  }

  @Transactional(propagation = Propagation.REQUIRED)
  public void insertAndUpdateOrderInfo(){
    Date date = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String updateTime = dateFormat.format(date);

    //步驟1:插入訂單記錄信息
    String[] insertParam = {"555555555", "977723233", updateTime, updateTime};
    transBusiness.insertData(insertParam);

    //步驟2:修改訂單記錄信息
    String[] updateParam = {"1111111111", updateTime, "1"};
    transBusiness.upateData(updateParam);
  }

}



@Service
public class TransBusiness {

  @Autowired
  JdbcTemplate dalClient;

  public void insertData(String[] param) {
    Map<String, Object> resultMap = new HashMap<>();
    String sql = "INSERT INTO test_order (`order_no`, `cust_no`,create_time,update_time) VALUES (?, ?,?,?)";

    int i = dalClient.update(sql, param);
    System.out.println("TransBusiness>>>insertData" + i);
    resultMap.put("插入的記錄數(shù)", i);
  }

  public void upateData(String[] param) {
    Map<String, Object> resultMap = new HashMap<>();
    String sql = "update test_order set order_no =?,update_time=? ? where id= ?";

    int i = dalClient.update(sql, param);
    System.out.println("TransBusiness>>>upateData" + i);
    resultMap.put("修改的記錄數(shù)", i);
  }

}

2.1自身調(diào)用事務(wù)失效解決方法1—在父方法中添加事務(wù)

通過(guò)doSomeThing()方法中添加事務(wù)性,可以解決1中事務(wù)自身調(diào)用失效的問(wèn)題。

示列驗(yàn)證:

OrderServiceImpl.insertAndUpdateOrderInfo方法中當(dāng)步驟1執(zhí)行完成后,數(shù)據(jù)庫(kù)中并不會(huì)存在該訂單記錄。當(dāng)執(zhí)行步驟2時(shí)發(fā)生了異常,整個(gè)事務(wù)發(fā)生了回滾。說(shuō)明才方法解決了1自身調(diào)用事務(wù)失效的問(wèn)題。

說(shuō)明:此處的@Transactional等同于 @Transactional(propagation = Propagation.REQUIRED) 表示支持當(dāng)前事務(wù),如果沒(méi)有事務(wù)就新建一個(gè)事務(wù),這是常見(jiàn)的選擇,也是spring默認(rèn)的事務(wù)傳播

@Override
  @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
  public void doSomeThing1() {
    insertAndUpdateOrderInfo();
  }

  public void insertAndUpdateOrderInfo(){
    Date date = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String updateTime = dateFormat.format(date);

    //步驟1:插入訂單記錄信息
    String[] insertParam = {"8888888888", "977723233", updateTime, updateTime};
    transBusiness.insertData(insertParam);

    //步驟2:修改訂單記錄信息
    String[] updateParam = {"1111111112", updateTime, "1"};
    transBusiness.upateData(updateParam);
  }

2.2自身調(diào)用事務(wù)失效解決方法2—將事務(wù)方法拆分到另外一個(gè)類(lèi)中

@Service
public class TransBusiness {

  @Autowired
  JdbcTemplate dalClient;

  @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
  public void insertAndUpdateOrderInfo(){
    Date date = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String updateTime = dateFormat.format(date);

    //步驟1:插入訂單記錄信息
    String[] insertParam = {"8888888888", "977723233", updateTime, updateTime};
    insertData(insertParam);

    //步驟2:修改訂單記錄信息
    String[] updateParam = {"1111111112", updateTime, "1"};
    upateData(updateParam);
  }

}

3.SQL規(guī)范于1992年提出了數(shù)據(jù)庫(kù)事務(wù)隔離級(jí)別,以此用來(lái)保證并發(fā)操作數(shù)據(jù)的正確性及一致性。Mysql的事務(wù)隔離級(jí)別由低往高可分為以下幾類(lèi):

1) READ UNCOMMITTED(讀取未提交的數(shù)據(jù))

  這是最不安全的一種級(jí)別,查詢語(yǔ)句在無(wú)鎖的情況下運(yùn)行,就讀取到別的未提交的數(shù)據(jù),造成臟讀,如果未提交的那個(gè)事務(wù)數(shù)據(jù)全部回滾了,而之前讀取了這個(gè)事務(wù)的數(shù)據(jù)即是臟數(shù)據(jù),這種數(shù)據(jù)不一致性讀造成的危害是可想而知的。

2) READ COMMITTED(讀取已提交的數(shù)據(jù))

  一個(gè)事務(wù)只能讀取數(shù)據(jù)庫(kù)中已經(jīng)提交過(guò)的數(shù)據(jù),解決了臟讀問(wèn)題,但不能重復(fù)讀,即一個(gè)事務(wù)內(nèi)的兩次查詢返回的數(shù)據(jù)是不一樣的。如第一次查詢金額是100,第二次去查詢可能就是50了,這就是不可重復(fù)讀取。

3) REPEATABLE READ(可重復(fù)讀取數(shù)據(jù),這也是Mysql默認(rèn)的隔離級(jí)別)

  一個(gè)事務(wù)內(nèi)的兩次無(wú)鎖查詢返回的數(shù)據(jù)都是一樣的,但別的事務(wù)的新增數(shù)據(jù)也能讀取到。比如另一個(gè)事務(wù)插入了一條數(shù)據(jù)并提交,這個(gè)事務(wù)第二次去讀取的時(shí)候發(fā)現(xiàn)多了一條之前查詢數(shù)據(jù)列表里面不存在的數(shù)據(jù),這時(shí)候就是傳說(shuō)的中幻讀了。這個(gè)級(jí)別避免了不可重復(fù)讀取,但不能避免幻讀的問(wèn)題。

4) SERIALIZABLE(可串行化讀)

  這是效率最低最耗費(fèi)資源的一個(gè)事務(wù)級(jí)別,和可重復(fù)讀類(lèi)似,但在自動(dòng)提交模式關(guān)閉情況下可串行化讀會(huì)給每個(gè)查詢加上共享鎖和排他鎖,意味著所有的讀操作之間不阻塞,但讀操作會(huì)阻塞別的事務(wù)的寫(xiě)操作,寫(xiě)操作也阻塞讀操作。

4.spring事務(wù)管理其實(shí)是對(duì)數(shù)據(jù)庫(kù)事務(wù)進(jìn)行了封裝而已,并提了5種事務(wù)隔離級(jí)別和7種事務(wù)傳播機(jī)制。

4.1聲明式事務(wù)(declarative transaction management)是Spring提供的對(duì)程序事務(wù)管理的方式之一。Spring使用AOP來(lái)完成聲明式的事務(wù)管理,因而聲明式事務(wù)是以方法為單位,Spring的事務(wù)屬性自然就在于描述事務(wù)應(yīng)用至方法上的策略,在Spring中事務(wù)屬性有以下參數(shù):

readOnly屬性的詳細(xì)理解:

1)readonly并不是所有數(shù)據(jù)庫(kù)都支持的,不同的數(shù)據(jù)庫(kù)下會(huì)有不同的結(jié)果。

2)設(shè)置了readonly后,connection都會(huì)被賦予readonly,效果取決于數(shù)據(jù)庫(kù)的實(shí)現(xiàn)。

a. 在oracle下測(cè)試,發(fā)現(xiàn)不支持readOnly,也就是不論Connection里的readOnly屬性是true還是false均不影響SQL的增刪改查;

b. 在mysql下測(cè)試,發(fā)現(xiàn)支持readOnly,設(shè)置為true時(shí),只能查詢,若增刪改會(huì)發(fā)生如下異常:

Caused by: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910)
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:792)

3)在ORM中,設(shè)置了readonly會(huì)賦予一些額外的優(yōu)化,例如在Hibernate中,會(huì)被禁止flush等。

4.2 spring 的 5種事務(wù)隔離級(jí)別

1) ISOLATION_DEFAULT     (使用后端數(shù)據(jù)庫(kù)默認(rèn)的隔離級(jí)別)

以下四個(gè)與JDBC的隔離級(jí)別相對(duì)應(yīng):

2) ISOLATION_READ_UNCOMMITTED (允許讀取尚未提交的更改,可能導(dǎo)致臟讀、幻影讀或不可重復(fù)讀)

3) ISOLATION_READ_COMMITTED (允許從已經(jīng)提交的并發(fā)事務(wù)讀取,可防止臟讀,但幻影讀和不可重復(fù)讀仍可能會(huì)發(fā)生)

4) ISOLATION_REPEATABLE_READ (對(duì)相同字段的多次讀取的結(jié)果是一致的,除非數(shù)據(jù)被當(dāng)前事務(wù)本身改變??煞乐古K讀和不可重復(fù)讀,但幻影讀仍可能發(fā)生)

5) ISOLATION_SERIALIZABLE (完全服從ACID的隔離級(jí)別,確保不發(fā)生臟讀、不可重復(fù)讀和幻影讀。這在所有隔離級(jí)別中也是最慢的,因?yàn)樗ǔJ峭ㄟ^(guò)完全鎖定當(dāng)前事務(wù)所涉及的數(shù)據(jù)表來(lái)完成的)

4.3 spring的7種事務(wù)傳播機(jī)制:

1) REQUIRED(需要事務(wù)): 業(yè)務(wù)方法需要在一個(gè)事務(wù)中運(yùn)行,如果方法運(yùn)行時(shí),已處在一個(gè)事務(wù)中,那么就加入該事務(wù),否則自己創(chuàng)建一個(gè)新的事務(wù).這是spring默認(rèn)的傳播行為;

2) NOT_SUPPORTED(不支持事務(wù)): 聲明方法需要事務(wù),如果方法沒(méi)有關(guān)聯(lián)到一個(gè)事務(wù),容器不會(huì)為它開(kāi)啟事務(wù).如果方法在一個(gè)事務(wù)中被調(diào)用,該事務(wù)會(huì)被掛起,在方法調(diào)用結(jié)束后,原先的事務(wù)便會(huì)恢復(fù)執(zhí)行;

3) REQUIREDS_NEW(需要新事務(wù)):業(yè)務(wù)方法總是會(huì)為自己發(fā)起一個(gè)新的事務(wù),如果方法已運(yùn)行在一個(gè)事務(wù)中,則原有事務(wù)被掛起,新的事務(wù)被創(chuàng)建,直到方法結(jié)束,新事務(wù)才結(jié)束,原先的事務(wù)才會(huì)恢復(fù)執(zhí)行;
備注:新建的事務(wù)如果沒(méi)有進(jìn)行異常捕獲,發(fā)生異常那么原事務(wù)方法也會(huì)發(fā)生回滾。(該結(jié)論經(jīng)過(guò)自測(cè)驗(yàn)證)

4) MANDATORY(強(qiáng)制性事務(wù)):只能在一個(gè)已存在事務(wù)中執(zhí)行。業(yè)務(wù)方法不能發(fā)起自己的事務(wù),如果業(yè)務(wù)方法在沒(méi)有事務(wù)的環(huán)境下調(diào)用,就拋異常

5) NEVER(不能存在事務(wù)):聲明方法絕對(duì)不能在事務(wù)范圍內(nèi)執(zhí)行,如果方法在某個(gè)事務(wù)范圍內(nèi)執(zhí)行,容器就拋異常.只有沒(méi)關(guān)聯(lián)到事務(wù),才正常執(zhí)行.

6) SUPPORTS(支持事務(wù)):如果業(yè)務(wù)方法在某個(gè)事務(wù)范圍內(nèi)被調(diào)用,則方法成為該事務(wù)的一部分,如果業(yè)務(wù)方法在事務(wù)范圍外被調(diào)用,則方法在沒(méi)有事務(wù)的環(huán)境下執(zhí)行.

7) NESTED(嵌套事務(wù)):如果一個(gè)活動(dòng)的事務(wù)存在,則運(yùn)行在一個(gè)嵌套的事務(wù)中.如果沒(méi)有活動(dòng)的事務(wù),則按REQUIRED屬性執(zhí)行.它使用了一個(gè)單獨(dú)的事務(wù),這個(gè)事務(wù)擁有多個(gè)可以回滾的保證點(diǎn).內(nèi)部事務(wù)回滾不會(huì)對(duì)外部事務(wù)造成影響, 它只對(duì)DataSourceTransactionManager 事務(wù)管理器起效.

思考:Nested和RequiresNew的區(qū)別:

a. RequiresNew每次都創(chuàng)建新的獨(dú)立的物理事務(wù),而Nested只有一個(gè)物理事務(wù);

b. Nested嵌套事務(wù)回滾或提交不會(huì)導(dǎo)致外部事務(wù)回滾或提交,但外部事務(wù)回滾將導(dǎo)致嵌套事務(wù)回滾,而 RequiresNew由于都是全新的事務(wù),所以之間是無(wú)關(guān)聯(lián)的;

c. Nested使用JDBC 3的保存點(diǎn)實(shí)現(xiàn),即如果使用低版本驅(qū)動(dòng)將導(dǎo)致不支持嵌套事務(wù)。

實(shí)際應(yīng)用中一般使用默認(rèn)的事務(wù)傳播行為,偶爾會(huì)用到RequiresNew和Nested方式。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java?lambda表達(dá)式與泛型整理總結(jié)

    Java?lambda表達(dá)式與泛型整理總結(jié)

    Lambda?表達(dá)式(lambda?expression)是一個(gè)匿名函數(shù),Lambda表達(dá)式基于數(shù)學(xué)中的λ演算得名。泛型編程,故如其名,是一個(gè)泛化的編程方式。其實(shí)現(xiàn)原理為程序員編寫(xiě)一個(gè)函數(shù)/類(lèi)的代碼示例,讓編譯器去填補(bǔ)出不同的函數(shù)實(shí)現(xiàn)
    2022-07-07
  • 深入學(xué)習(xí)Java同步機(jī)制中的底層實(shí)現(xiàn)

    深入學(xué)習(xí)Java同步機(jī)制中的底層實(shí)現(xiàn)

    在多線程編程中我們會(huì)遇到很多需要使用線程同步機(jī)制去解決的并發(fā)問(wèn)題,這些同步機(jī)制是如何實(shí)現(xiàn)的呢?下面和小編來(lái)一起學(xué)習(xí)吧
    2019-05-05
  • idea激活A(yù)ctivateJrebel熱部署的方法詳解

    idea激活A(yù)ctivateJrebel熱部署的方法詳解

    這篇文章主要介紹了idea激活A(yù)ctivateJrebel熱部署的方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • 基于SpringBoot中activeMq的JmsTemplate的實(shí)例

    基于SpringBoot中activeMq的JmsTemplate的實(shí)例

    這篇文章主要介紹了基于SpringBoot中activeMq的JmsTemplate的實(shí)例問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Mac下如何查看已安裝的jdk版本及其安裝目錄

    Mac下如何查看已安裝的jdk版本及其安裝目錄

    這篇文章主要介紹了Mac下如何查看已安裝的jdk版本及其安裝目錄問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • SpringBoot熔斷機(jī)制之CircuitBreaker詳解

    SpringBoot熔斷機(jī)制之CircuitBreaker詳解

    這篇文章主要介紹了SpringBoot熔斷機(jī)制之CircuitBreaker詳解,SpringBoot的熔斷機(jī)制在微服務(wù)架構(gòu)中扮演著重要角色,其中CircuitBreaker是其核心機(jī)制之一,用于防止服務(wù)的異常狀態(tài)影響到整個(gè)系統(tǒng)的運(yùn)作,需要的朋友可以參考下
    2023-10-10
  • 深入淺析Java 循環(huán)中標(biāo)簽的作用

    深入淺析Java 循環(huán)中標(biāo)簽的作用

    這篇文章主要介紹了深入淺析Java 循環(huán)中標(biāo)簽的作用的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • 詳解Java I/O流中的字符流有哪些

    詳解Java I/O流中的字符流有哪些

    字節(jié)流的功能已經(jīng)十分強(qiáng)大,幾乎可以直接或間接地處理任何類(lèi)型的輸入/輸出操作,但它卻不能直接操作16位的Unicode字符,這就需要使用字符流,所以在今天的內(nèi)容中,小編會(huì)給大家講解IO流中的字符流,希望各位能夠繼續(xù)耐心學(xué)習(xí)
    2023-10-10
  • IDEA的下載和使用安裝詳細(xì)圖文教程

    IDEA的下載和使用安裝詳細(xì)圖文教程

    這篇文章主要介紹了IDEA的下載和使用安裝,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • SimpleDateFormat格式化日期問(wèn)題

    SimpleDateFormat格式化日期問(wèn)題

    這篇文章主要介紹了SimpleDateFormat格式化日期問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06

最新評(píng)論