日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringTX

發(fā)布時(shí)間:2023/12/3 javascript 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringTX 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • SpringTX的介紹
    • SpringTX的使用代碼示例
    • 聲明式事務(wù)中屬性解釋
    • SpringBoot中AOP事務(wù)配置

SpringTX的介紹

問題:

在學(xué)習(xí)了Spring整合mybatis后,我們可以直接從Spring容器中獲取mapper層的實(shí)例化對(duì)象完成數(shù)據(jù)庫操作。而在業(yè)務(wù)層方法中很多時(shí)候因?yàn)闃I(yè)務(wù)邏輯的復(fù)雜性,會(huì)出現(xiàn)在業(yè)務(wù)層方法中調(diào)用多個(gè)數(shù)據(jù)庫操作。而之前我們學(xué)習(xí)過事務(wù)的管理,在同一個(gè)業(yè)務(wù)中只要有一個(gè)數(shù)據(jù)庫操作執(zhí)行失敗,其他的就算執(zhí)行成功也會(huì)一并回滾。但是在Spring整合Mybatis后,我們獲取的直接是Mapper接口的實(shí)例化對(duì)象,而事務(wù)的管理需要使用connection對(duì)象來完成或者SqlSession對(duì)象來完成,那么在Spring整合Mybatis后如何聲明事務(wù)管理代碼呢?

解決:

假如我們能夠從Spring容器中獲取SqlSession對(duì)象,那么在業(yè)務(wù)方法A中調(diào)用了多次的數(shù)據(jù)庫操作,我們就需要在A業(yè)務(wù)方法中的業(yè)務(wù)邏輯代碼之前開啟事務(wù)管理,在邏輯代碼之后進(jìn)行提交或者回滾。假如有10個(gè)業(yè)務(wù)方法需要聲明事務(wù)管理,則需要聲明10次,過于麻煩,而且需要修改業(yè)務(wù)方法的源碼。基于以上的流程我們發(fā)現(xiàn),該擴(kuò)展流程完全符合AOP的基本規(guī)范,考慮使用SpringAOP的方式來對(duì)業(yè)務(wù)方法進(jìn)行擴(kuò)展,聲明環(huán)繞通知,在環(huán)繞通知中聲明事務(wù)管理代碼,切點(diǎn)為要進(jìn)行事務(wù)管理的業(yè)務(wù)方法。
但是我們又無法直接獲取到SqlSession對(duì)象,造成無法在環(huán)繞通 知中聲明事務(wù)管理代碼,又發(fā)現(xiàn)事務(wù)管理的代碼是重復(fù)的代碼, 那么能不能讓Spring官方給我們直接提供一個(gè)和Spring容器直 接整合好的事務(wù)管理類。答案是可以的。

理論圖:

實(shí)現(xiàn):

Spring的TX

概念:

編程式事務(wù): 事務(wù)管理代碼由程序員自己編寫。
聲明式事務(wù): 事務(wù)管理代碼由第三方直接提供,程序員直接將其組裝到功能中即可。

[2] SpringTX的使用流程
① 導(dǎo)入相關(guān)jar包
i. SpringIOC的jar
ii. SpringAOP的jar
iii. SpringTX的jar
iv. Spring整合Mybatis的jar
v. Mybatis的jar
vi. 數(shù)據(jù)庫的驅(qū)動(dòng)的jar
② 搭建Spring整合Mybatis的項(xiàng)目
③ 在applicationcontext.xml文件中配置事務(wù)管理bean
④ 在applicationcontext.xml文件中配置業(yè)務(wù)層bean
⑤ 在applicationcontext.xml文件中配置事務(wù)管理切面
⑥ 正常編寫代碼完成功能開發(fā)。

SpringTX的使用代碼示例

[1] 在數(shù)據(jù)庫中創(chuàng)建賬戶信息表(銀行轉(zhuǎn)賬)

[2] 在web項(xiàng)目中導(dǎo)入相關(guān)的jar文件

[3] 搭建Spring整合Mybatis開發(fā)基板
① 在src下創(chuàng)建MVC包結(jié)構(gòu)
② 在src下創(chuàng)建并配置applicationcontext.xml
③ 在web.xml文件中配置Spring的資源

[4] 聲明mapper層完成銀行轉(zhuǎn)賬的數(shù)據(jù)庫操作
① 在mapper包下創(chuàng)建AccountMapper接口并聲明轉(zhuǎn)賬方法

② 在AccountMapper的數(shù)據(jù)庫操作方法上使用注解聲明SQL語句

[5] 聲明業(yè)務(wù)層方法完成銀行轉(zhuǎn)賬
① 在service層中聲明接口AccountService,并聲明轉(zhuǎn)賬方 法。

② 在service層下創(chuàng)建包impl,并聲明接口的實(shí)現(xiàn)類AccountServiceImpl,并完成轉(zhuǎn)賬業(yè)務(wù)方法功能。

[6] 在controller層聲明類TestAccount測試銀行轉(zhuǎn)賬功能

[7] 在applicationcontext.xml文件中配置Spring的事務(wù)管理(重點(diǎn)掌握)

聲明式事務(wù)中屬性解釋

  • name=”” 哪些方法需要有事務(wù)控制
    1.1 支持*通配符
  • readonly=”boolean” 是否是只讀事務(wù).
    2.1 如果為true,告訴數(shù)據(jù)庫此事務(wù)為只讀事務(wù).數(shù)據(jù)化優(yōu)化,會(huì)對(duì)性能有一定提升,所以只要是查詢的方法,建議使用此數(shù)據(jù).
    2.2 如果為false(默認(rèn)值),事務(wù)需要提交的事務(wù).建議新增,刪除,修改.
  • propagation 控制事務(wù)傳播行為.
    3.1 當(dāng)一個(gè)具有事務(wù)控制的方法被另一個(gè)有事務(wù)控制的方法調(diào)用后,需要如何管理事務(wù)(新建事務(wù)?在事務(wù)中執(zhí)行?把事務(wù)掛起?報(bào)異常?)
    3.2 REQUIRED (默認(rèn)值): 如果當(dāng)前有事務(wù),就在事務(wù)中執(zhí)行,如果當(dāng)前沒有事務(wù),新建一個(gè)事務(wù).
    3.3 SUPPORTS:如果當(dāng)前有事務(wù)就在事務(wù)中執(zhí)行,如果當(dāng)前沒有事務(wù),就在非事務(wù)狀態(tài)下執(zhí)行.
    3.4 MANDATORY:必須在事務(wù)內(nèi)部執(zhí)行,如果當(dāng)前有事務(wù),就在事務(wù)中執(zhí)行,如果沒有事務(wù),報(bào)錯(cuò).
    3.5 REQUIRES_NEW:必須在事務(wù)中執(zhí)行,如果當(dāng)前沒有事務(wù),新建事務(wù),如果當(dāng)前有事務(wù),把當(dāng)前事務(wù)掛起.
    3.6 NOT_SUPPORTED:必須在非事務(wù)下執(zhí)行,如果當(dāng)前沒有事務(wù),正常執(zhí)行,如果當(dāng)前有事務(wù),把當(dāng)前事務(wù)掛起.
    3.7 NEVER:必須在非事務(wù)狀態(tài)下執(zhí)行,如果當(dāng)前沒有事務(wù),正常執(zhí)行,如果當(dāng)前有事務(wù),報(bào)錯(cuò).
    3.8 NESTED:必須在事務(wù)狀態(tài)下執(zhí)行.如果沒有事務(wù),新建事務(wù),如果當(dāng)前有事務(wù),創(chuàng)建一個(gè)嵌套事務(wù).
  • 4.isolation=”” 事務(wù)隔離級(jí)別
    4.1 在多線程或并發(fā)訪問下如何保證訪問到的數(shù)據(jù)具有完整性的.
    4.2 臟讀:
    4.2.1 一個(gè)事務(wù)(A)讀取到另一個(gè)事務(wù)(B)中未提交的數(shù)據(jù),另一個(gè)事務(wù)中數(shù)據(jù)可能進(jìn)行了改變,此時(shí)A事務(wù)讀取的數(shù)據(jù)可能和數(shù)據(jù)庫中數(shù)據(jù)是不一致的,此時(shí)認(rèn)為數(shù)據(jù)是臟數(shù)據(jù),讀取臟數(shù)據(jù)過程叫做臟讀.
    4.3 不可重復(fù)讀:
    4.3.1 主要針對(duì)的是某行數(shù)據(jù).(或行中某列)
    4.3.2 主要針對(duì)的操作是修改操作.
    4.3.3 兩次讀取在同一個(gè)事務(wù)內(nèi)
    4.3.4 當(dāng)事務(wù)A第一次讀取事務(wù)后,事務(wù)B對(duì)事務(wù)A讀取的數(shù)據(jù)進(jìn)行修改,事務(wù)A中再次讀取的數(shù)據(jù)和之前讀取的數(shù)據(jù)不一致,過程不可重復(fù)讀.
    4.4 幻讀:
    4.4.1 主要針對(duì)的操作是新增或刪除
    4.4.2 兩次事務(wù)的結(jié)果.
    4.4.3 事務(wù)A按照特定條件查詢出結(jié)果,事務(wù)B新增了一條符合條件的數(shù)據(jù).事務(wù)A中查詢的數(shù)據(jù)和數(shù)據(jù)庫中的數(shù)據(jù)不一致的,事務(wù)A好像出現(xiàn)了幻覺,這種情況稱為幻讀.
    4.5 DEFAULT: 默認(rèn)值,由底層數(shù)據(jù)庫自動(dòng)判斷應(yīng)該使用什么隔離界別
    4.6 READ_UNCOMMITTED: 可以讀取未提交數(shù)據(jù),可能出現(xiàn)臟讀,不重復(fù)讀,幻讀.
    4.6.1 效率最高.
    4.7 READ_COMMITTED:只能讀取其他事務(wù)已提交數(shù)據(jù).可以防止臟讀,可能出現(xiàn)不可重復(fù)讀和幻讀.
    4.8 REPEATABLE_READ: 讀取的數(shù)據(jù)被添加鎖,防止其他事務(wù)修改此數(shù)據(jù),可以防止不可重復(fù)讀.臟讀,可能出現(xiàn)幻讀.
    4.9 SERIALIZABLE: 排隊(duì)操作,對(duì)整個(gè)表添加鎖.一個(gè)事務(wù)在操作數(shù)據(jù)時(shí),另一個(gè)事務(wù)等待事務(wù)操作完成后才能操作這個(gè)表.
    4.9.1 最安全的
    4.9.2 效率最低的.

    5.rollback-for=”異常類型全限定路徑”
    5.1 當(dāng)出現(xiàn)什么異常時(shí)需要進(jìn)行回滾
    5.2 建議:給定該屬性值.
    5.2.1 手動(dòng)拋異常一定要給該屬性值.

    6.no-rollback-for=””
    6.1 當(dāng)出現(xiàn)什么異常時(shí)不滾回事務(wù).

    SpringBoot中AOP事務(wù)配置

    在SpringBoot里面可以直接導(dǎo)入 Spring 的配置文件,同時(shí)大部分的開發(fā)者都是基于配置文件的形式進(jìn)行事務(wù)定義的,但是如果真的要做一個(gè)符合于 SpringBoot應(yīng)用開發(fā),那么就需要考慮避免XML配置文件的出現(xiàn),所以直接基于Bean的模式來實(shí)現(xiàn)AOP事務(wù)配置。
    1、【microboot-database子模塊】編寫一個(gè)事務(wù)配置類

    package com.yootk.config;import org.aspectj.weaver.patterns.HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor; import org.springframework.aop.Advisor; import org.springframework.aop.aspectj.AspectJExpressionPointcut; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionManager; import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource; import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute; import org.springframework.transaction.interceptor.TransactionAttribute; import org.springframework.transaction.interceptor.TransactionInterceptor;import java.util.HashMap; import java.util.Map;public class TransactionConfig { // 事務(wù)配置類private static final int TRANSACTION_METHOD_TIMEOUT = 5; // 事務(wù)處理的超時(shí)時(shí)間private static final String AOP_POINTCUT_EXPRESSION = "execution (* com.yootk..service.*.*(..))";@Autowiredprivate TransactionManager transactionManager; // 事務(wù)管理器@Bean("txAdvice")public TransactionInterceptor transactionInterceptorConfig() {// 配置數(shù)據(jù)讀取事務(wù)規(guī)則RuleBasedTransactionAttribute readOnlyAttribute = new RuleBasedTransactionAttribute();readOnlyAttribute.setReadOnly(true); // 只讀事務(wù)readOnlyAttribute.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); // 非事務(wù)運(yùn)行// 配置了數(shù)據(jù)更新事務(wù)規(guī)則RuleBasedTransactionAttribute requiredAttribute = new RuleBasedTransactionAttribute();requiredAttribute.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); // 事務(wù)開啟requiredAttribute.setTimeout(TRANSACTION_METHOD_TIMEOUT); // 事務(wù)處理超時(shí)時(shí)間// 配置所有要進(jìn)行事務(wù)處理的方法名稱定義Map<String, TransactionAttribute> transactionAttributeMap = new HashMap<>();transactionAttributeMap.put("add*", requiredAttribute);transactionAttributeMap.put("edit*", requiredAttribute);transactionAttributeMap.put("delete*", requiredAttribute);transactionAttributeMap.put("list*", readOnlyAttribute);transactionAttributeMap.put("get*", readOnlyAttribute);NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();source.setNameMap(transactionAttributeMap); // 配置方法名稱的映射TransactionInterceptor interceptor = new TransactionInterceptor(transactionManager, source);return interceptor;}@Bean("txAdvisor")public Advisor transactionAdvisor(@Autowired TransactionInterceptor interceptor) {AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();pointcut.setExpression(AOP_POINTCUT_EXPRESSION);return new DefaultPointcutAdvisor(pointcut, interceptor);} }

    2、【microboot-database子模塊】既然已經(jīng)創(chuàng)建好了事務(wù)相關(guān)處理類,那么下面就在IMemberService 業(yè)務(wù)接口里面擴(kuò)充一個(gè)方法。這個(gè)方法有可能會(huì)產(chǎn)生異常。

    package com.yootk.service;public interface IMemberService {public boolean addBatch(String ... mid); // 批量數(shù)據(jù)增加 } package com.yootk.service.impl.impl;import com.yootk.dao.IMemberDAO; import com.yootk.service.IMemberService; import com.yootk.vo.Member; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;@Service public class MemberServiceImpl implements IMemberService {@Autowiredprivate IMemberDAO memberDAO;@Overridepublic boolean addBatch(String... mid) {for (String id : mid) {Member vo = new Member();vo.setMid(id); // 如果id重復(fù)則會(huì)出現(xiàn)更新異常vo.setName("老李");this.memberDAO.insert(vo);}return true;} }

    3、【microboot-database子模塊】在實(shí)現(xiàn)類中進(jìn)行數(shù)據(jù)的增加:

    package com.yootk.test;import com.baomidou.mybatisplus.core.metadata.IPage; import com.yootk.StartSpringBootDatabaseApplication; import com.yootk.service.IMemberService; import com.yootk.vo.Member; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.web.WebAppConfiguration;import java.util.Date; import java.util.Set;@ExtendWith(SpringExtension.class) // 使用JUnit5測試工具 @WebAppConfiguration // 啟動(dòng)WEB運(yùn)行環(huán)境 @SpringBootTest(classes = StartSpringBootDatabaseApplication.class) // 配置程序啟動(dòng)類 public class TestMemberService { // 編寫測試類@Autowiredprivate IMemberService memberService;@Testpublic void testAddBatchRepeatID() { //傳遞數(shù)據(jù)庫中已有的idthis.memberService.addBatch("muyan", "yootk", "lixinghua");}@Testpublic void testAddBatchNoRepeatID() { //傳遞數(shù)據(jù)庫中沒有有的idthis.memberService.addBatch("muyan-happy", "yootk-happy", "lixinghua-happy"");} }

    4、【程序執(zhí)行結(jié)果】

    testAddBatchRepeatID

    testAddBatchNoRepeatID
    加入成功

    總結(jié)

    以上是生活随笔為你收集整理的SpringTX的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。