中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

廣東建設(shè)網(wǎng)工程信息網(wǎng)站無(wú)錫網(wǎng)站建設(shè)seo

廣東建設(shè)網(wǎng)工程信息網(wǎng)站,無(wú)錫網(wǎng)站建設(shè)seo,微網(wǎng)站建設(shè)市場(chǎng)分析,平面網(wǎng)頁(yè)設(shè)計(jì)是什么一、事務(wù)的概念 百度百科: 事務(wù)(Transaction),一般是指要做的或所做的事情。在計(jì)算機(jī)術(shù)語(yǔ)中是指訪問(wèn)并可能更新數(shù)據(jù)庫(kù)中各種數(shù)據(jù)項(xiàng)的一個(gè)程序執(zhí) 行單元(unit)。事務(wù)通常由高級(jí)數(shù)據(jù)庫(kù)操縱語(yǔ)言或編程語(yǔ)言(如SQL&#x…

一、事務(wù)的概念

百度百科:

事務(wù)(Transaction),一般是指要做的或所做的事情。在計(jì)算機(jī)術(shù)語(yǔ)中是指訪問(wèn)并可能更新數(shù)據(jù)庫(kù)中各種數(shù)據(jù)項(xiàng)的一個(gè)程序執(zhí)
行單元(unit)。事務(wù)通常由高級(jí)數(shù)據(jù)庫(kù)操縱語(yǔ)言或編程語(yǔ)言(如SQLC++Java)書(shū)寫(xiě)的用戶程序的執(zhí)行所引起,并用形如
begin transaction和end transaction語(yǔ)句(或函數(shù)調(diào)用)來(lái)界定。事務(wù)由事務(wù)開(kāi)始(begin transaction)和事務(wù)結(jié)
束(end transaction)之間執(zhí)行的全體操作組成。

事務(wù)有四個(gè)特點(diǎn):原子性、一致性、隔離性和持久性。

事務(wù)管理在系統(tǒng)開(kāi)發(fā)中是不可缺少的一部分,Spring提供了很好事務(wù)管理機(jī)制,主要分為編程式事務(wù)聲明式事務(wù)兩種。

1、編程式事務(wù)

是指在代碼中手動(dòng)的管理事務(wù)的提交、回滾等操作,代碼侵入性比較強(qiáng)。

編程式事務(wù)方式需要開(kāi)發(fā)者在代碼中手動(dòng)的管理事務(wù)的開(kāi)啟、提交、回滾等操作。

public void test() {TransactionDefinition def = new DefaultTransactionDefinition();TransactionStatus status = transactionManager.getTransaction(def);try {// 事務(wù)操作// 事務(wù)提交transactionManager.commit(status);} catch (DataAccessException e) {// 事務(wù)提交transactionManager.rollback(status);throw e;}}

如以上代碼,開(kāi)發(fā)者可以通過(guò)API自己控制事務(wù)。

2、聲明式事務(wù)

基于AOP(面向切面),它將具體業(yè)務(wù)與事務(wù)處理部分解耦,代碼侵入性很低,所以在實(shí)際開(kāi)發(fā)中聲明式事務(wù)用的比較多。聲明式事務(wù)也有兩種實(shí)現(xiàn)方式,一是基于TX和AOP的xml配置文件方式,二種就是基于@Transactional注解了。

聲明式事務(wù)管理方法允許開(kāi)發(fā)者配置的幫助下來(lái)管理事務(wù),而不需要依賴底層API進(jìn)行硬編碼。開(kāi)發(fā)者可以只使用注解或基于配置的 XML 來(lái)管理事務(wù)。

    @Transactional@GetMapping("/myTest")public void test() {Student student = new Student();int insert = myMapper.insert(student);}

聲明式事務(wù)對(duì)代碼沒(méi)有侵入性,方法內(nèi)只需要寫(xiě)業(yè)務(wù)邏輯就可以了,幫助我們節(jié)省了很多代碼,他會(huì)自動(dòng)幫我們進(jìn)行事務(wù)的開(kāi)啟、提交以及回滾等操作,把程序員從事務(wù)管理中解放出來(lái)??梢哉f(shuō)優(yōu)點(diǎn)很明顯,但是這種方式的缺點(diǎn)也很明顯。

問(wèn)題一:聲明式事務(wù)的粒度問(wèn)題

首先,聲明式事務(wù)有一個(gè)局限,那就是他的最小粒度要作用在方法上。

也就是說(shuō),如果想要給一部分代碼塊增加事務(wù)的話,那就需要把這個(gè)部分代碼塊單獨(dú)獨(dú)立出來(lái)作為一個(gè)方法。

在大事務(wù)耗時(shí)過(guò)長(zhǎng)需要高并發(fā)優(yōu)化的情況下不建議使用聲明式事務(wù),建議采用上面提到的編程式事務(wù)方式。

問(wèn)題二:聲明式事務(wù)容易被開(kāi)發(fā)者忽略

而事務(wù)一旦被忽略就容易造成很多故障

首先,如果開(kāi)發(fā)者沒(méi)有注意到一個(gè)方法是被事務(wù)嵌套的,那么就可能會(huì)再方法中加入一些如RPC遠(yuǎn)程調(diào)用、消息發(fā)送、緩存更新、文件寫(xiě)入等操作。

我們知道,這些操作如果被包在事務(wù)中,有兩個(gè)問(wèn)題:

1、這些操作自身是無(wú)法回滾的,這就會(huì)導(dǎo)致數(shù)據(jù)的不一致??赡躌PC調(diào)用成功了,但是本地事務(wù)回滾了,可是PRC調(diào)用無(wú)法回滾了(這里不討論分布式事務(wù))。

2、在事務(wù)中有遠(yuǎn)程調(diào)用,就會(huì)拉長(zhǎng)整個(gè)事務(wù)。那么久會(huì)導(dǎo)致本事務(wù)的數(shù)據(jù)庫(kù)連接一直被占用,那么如果類似操作過(guò)多,就會(huì)導(dǎo)致數(shù)據(jù)庫(kù)連接池耗盡。

有些時(shí)候,即使沒(méi)有在事務(wù)中進(jìn)行遠(yuǎn)程操作,但是有些人還是可能會(huì)不經(jīng)意的進(jìn)行一些內(nèi)存操作,如運(yùn)算?;蛘呷绻龅椒謳?kù)分表的情況,有可能不經(jīng)意間進(jìn)行跨庫(kù)操作。

問(wèn)題三:聲明式事務(wù)用不對(duì)在某些場(chǎng)景下容易失效

這個(gè)問(wèn)題后面我們著重講述一下失效的幾種場(chǎng)景。

下面我們就講講聲明式事務(wù)使用的@Transactional注解。

二、@Transactional介紹

1、@Transactional 可以作用在接口、類、類方法

作用于類:當(dāng)把@Transactional 注解放在類上時(shí),表示所有該類的public方法都配置相同的事務(wù)屬性信息。

作用于方法:當(dāng)類配置了@Transactional,方法也配置了@Transactional,方法的事務(wù)會(huì)覆蓋類的事務(wù)配置信息。

作用于接口:不推薦這種使用方法,因?yàn)橐坏?biāo)注在Interface上并且配置了Spring AOP 使用CGLib動(dòng)態(tài)代理,將會(huì)導(dǎo)致@Transactional注解失效。

 @Transactional@RestController@RequestMappingpublic class MyController {@Autowiredprivate StudentMapper studentMapper;@Transactional(rollbackFor = Exception.class)@GetMapping("/test")public void test() throws Exception {       Student student = new Student();student.setName("chamption-Dai")int insert = studentMapper.insert(cityInfoDict);}
}

2、@Transactional注有哪些屬性?

屬性類型描述
valueString可選的限定描述符,指定使用的事務(wù)管理器
propagationenum: Propagation可選的事務(wù)傳播行為設(shè)置
isolationenum: Isolation可選的事務(wù)隔離級(jí)別設(shè)置
readOnlyboolean讀寫(xiě)或只讀事務(wù),默認(rèn)讀寫(xiě)
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ù)組

propagation屬性

propagation 代表事務(wù)的傳播行為,默認(rèn)值為 Propagation.REQUIRED,其他的屬性信息如下:

屬性說(shuō)明
Propagation.REQUIRED如果當(dāng)前存在事務(wù),則加入該事務(wù),如果當(dāng)前不存在事務(wù),則創(chuàng)建一個(gè)新的事務(wù)。( 也就是說(shuō)如果A方法和B方法都添加了注解,在默認(rèn)傳播模式下,A方法內(nèi)部調(diào)用B方法,會(huì)把兩個(gè)方法的事務(wù)合并為一個(gè)事務(wù) )
Propagation.SUPPORTS如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前不存在事務(wù),則以非事務(wù)的方式繼續(xù)運(yùn)行。
Propagation.MANDATORY如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前不存在事務(wù),則拋出異常。
Propagation.REQUIRES_NEW重新創(chuàng)建一個(gè)新的事務(wù),如果當(dāng)前存在事務(wù),暫停當(dāng)前的事務(wù)。( 當(dāng)類A中的 a 方法用默認(rèn)Propagation.REQUIRED模式,類B中的 b方法加上用 Propagation.REQUIRES_NEW模式,然后在 a 方法中調(diào)用 b方法操作數(shù)據(jù)庫(kù),然而 a方法拋出異常后,b方法并沒(méi)有進(jìn)行回滾,因?yàn)镻ropagation.REQUIRES_NEW會(huì)暫停 a方法的事務(wù) )
Propagation.NOT_SUPPORTED以非事務(wù)的方式運(yùn)行,如果當(dāng)前存在事務(wù),暫停當(dāng)前的事務(wù)。
Propagation.NEVER以非事務(wù)的方式運(yùn)行,如果當(dāng)前存在事務(wù),則拋出異常。
Propagation.NESTED和 Propagation.REQUIRED 效果一樣。

isolation 屬性

isolation :事務(wù)的隔離級(jí)別,默認(rèn)值為 Isolation.DEFAULT。

Isolation.DEFAULT:使用底層數(shù)據(jù)庫(kù)默認(rèn)的隔離級(jí)別。

Isolation.READ_UNCOMMITTED

Isolation.READ_COMMITTED

Isolation.REPEATABLE_READ

Isolation.SERIALIZABLE

timeout 屬性

timeout :事務(wù)的超時(shí)時(shí)間,默認(rèn)值為 -1。如果超過(guò)該時(shí)間限制但事務(wù)還沒(méi)有完成,則自動(dòng)回滾事務(wù)。

示例:

@Service
public class UserServiceImpl implements UserService{// 加載mapper
@Autowired
private UserMapper usermapper;@Transactional(propagation=Propagation.REQUIRED,timeout=5) // 啟用事務(wù)管理
public void myTransaction(User addUser, User updateuser) {System.out.println("---- 方法開(kāi)始 ");usermapper.add(addUser);try {Thread.sleep(6000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}usermapper.update(updateuser);System.out.println("----方法結(jié)束 ");
}
}

運(yùn)行結(jié)果:

在這里插入圖片描述

最終,由于事務(wù)超時(shí),事務(wù)回滾。
運(yùn)行的時(shí)候,由于事務(wù)超時(shí),就會(huì)報(bào)錯(cuò) TransactionTimedOutException:…

readOnly 屬性

readOnly :指定事務(wù)是否為只讀事務(wù),默認(rèn)值為 false;為了忽略那些不需要事務(wù)的方法,比如讀取數(shù)據(jù),可以設(shè)置 read-only 為 true。

rollbackFor 屬性

rollbackFor :用于指定能夠觸發(fā)事務(wù)回滾的異常類型,可以指定多個(gè)異常類型。

noRollbackFor屬性

noRollbackFor:拋出指定的異常類型,不回滾事務(wù),也可以指定多個(gè)異常類型。

三、@Transactional失效場(chǎng)景

接下來(lái)我們結(jié)合具體的代碼分析一下哪些場(chǎng)景下,@Transactional 注解會(huì)失效。

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

如果Transactional注解應(yīng)用在非public 修飾的方法上,Transactional將會(huì)失效。

在這里插入圖片描述
圖片來(lái)自“程序員那點(diǎn)事”

之所以會(huì)失效是因?yàn)樵赟pring AOP 代理時(shí),如上圖所示 TransactionInterceptor (事務(wù)攔截器)在目標(biāo)方法執(zhí)行前后進(jìn)行攔截,DynamicAdvisedInterceptor(CglibAopProxy 的內(nèi)部類)的 intercept 方法或 JdkDynamicAopProxy 的 invoke 方法會(huì)間接調(diào)用 AbstractFallbackTransactionAttributeSource的 computeTransactionAttribute 方法,獲取Transactional 注解的事務(wù)配置信息。

protected TransactionAttribute computeTransactionAttribute(Method method,Class<?> targetClass) {// Don't allow no-public methods as required.if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {return null;
}

此方法會(huì)檢查目標(biāo)方法的修飾符是否為 public,不是 public則不會(huì)獲取@Transactional 的屬性配置信息。

注意:protected、private 修飾的方法上使用 @Transactional 注解,雖然事務(wù)無(wú)效,但不會(huì)有任何報(bào)錯(cuò),這是我們很容犯錯(cuò)的一點(diǎn)。

2、@Transactional 注解屬性 propagation 設(shè)置錯(cuò)誤

這種失效是由于配置錯(cuò)誤,若是錯(cuò)誤的配置以下三種 propagation,事務(wù)將不會(huì)發(fā)生回滾。

  • TransactionDefinition.PROPAGATION_SUPPORTS:如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒(méi)有事務(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ù),則拋出異常。

3、@Transactional 注解屬性 rollbackFor 設(shè)置錯(cuò)誤

rollbackFor 可以指定能夠觸發(fā)事務(wù)回滾的異常類型。Spring默認(rèn)拋出了未檢查unchecked異常(繼承自 RuntimeException的異常)或者 Error才回滾事務(wù);其他異常不會(huì)觸發(fā)回滾事務(wù)。如果在事務(wù)中拋出其他類型的異常,但卻期望 Spring 能夠回滾事務(wù),就需要指定 rollbackFor屬性。
在這里插入圖片描述

在這里插入圖片描述

// 希望自定義的異常可以進(jìn)行回滾
@Transactional(propagation= Propagation.REQUIRED,rollbackFor= MyException.class
若在目標(biāo)方法中拋出的異常是 rollbackFor 指定的異常的子類,事務(wù)同樣會(huì)回滾。Spring源碼如下:

private int getDepth(Class<?> exceptionClass, int depth) {if (exceptionClass.getName().contains(this.exceptionName)) {// Found it!return depth;}// If we've gone as far as we can go and haven't found it...if (exceptionClass == Throwable.class) {return -1;}return getDepth(exceptionClass.getSuperclass(), depth + 1);
}

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

開(kāi)發(fā)中避免不了會(huì)對(duì)同一個(gè)類里面的方法調(diào)用,比如有一個(gè)類Test,它的一個(gè)方法A,A再調(diào)用本類的方法B(不論方法B是用public還是private修飾),但方法A沒(méi)有聲明注解事務(wù),而B(niǎo)方法有。則外部調(diào)用方法A之后,方法B的事務(wù)是不會(huì)起作用的。這也是經(jīng)常犯錯(cuò)誤的一個(gè)地方。

那為啥會(huì)出現(xiàn)這種情況?其實(shí)這還是由于使用Spring AOP代理造成的,因?yàn)橹挥挟?dāng)事務(wù)方法被當(dāng)前類以外的代碼調(diào)用時(shí),才會(huì)由Spring生成的代理對(duì)象來(lái)管理。

//@Transactional  去掉事務(wù)@GetMapping("/test")private Integer A() throws Exception {CityInfoDict cityInfoDict = new CityInfoDict();cityInfoDict.setCityName("2");/*** B 插入字段為 3的數(shù)據(jù)*/this.insertB();/*** A 插入字段為 2的數(shù)據(jù)*/int insert = cityInfoDictMapper.insert(cityInfoDict);return insert;}@Transactional()public Integer insertB() throws Exception {CityInfoDict cityInfoDict = new CityInfoDict();cityInfoDict.setCityName("3");cityInfoDict.setParentCityId(3);return cityInfoDictMapper.insert(cityInfoDict);}

5、異常被你的 catch“吃了”導(dǎo)致@Transactional失效

這種情況是最常見(jiàn)的一種@Transactional注解失效場(chǎng)景

 1    @Transactional2    private Integer A() throws Exception {3        int insert = 0;4        try {5            CityInfoDict cityInfoDict = new CityInfoDict();6            cityInfoDict.setCityName("Champtional-Dai");7            cityInfoDict.setParentCityId(1111);8            /**9             * A 插入字段為 2的數(shù)據(jù)
10             */
11            insert = cityInfoDictMapper.insert(cityInfoDict);
12            /**
13             * B 插入字段為 3的數(shù)據(jù)
14             */
15            b.insertB();
16        } catch (Exception e) {
17            e.printStackTrace();
18        }
19    }

問(wèn):如果B方法內(nèi)部拋了異常,而A方法此時(shí)try catch了B方法的異常,那這個(gè)事務(wù)還能正?;貪L嗎?

答案:不能!

會(huì)拋出異常:

org.springframework.transaction.UnexpectedRollbackException:
Transaction rolled back because it has been marked as rollback-only

因?yàn)楫?dāng)ServiceB中拋出了一個(gè)異常以后,ServiceB標(biāo)識(shí)當(dāng)前事務(wù)需要rollback。但是ServiceA中由于你手動(dòng)的捕獲這個(gè)異常并進(jìn)行處理,ServiceA認(rèn)為當(dāng)前事務(wù)應(yīng)該正常commit。此時(shí)就出現(xiàn)了前后不一致,也就是因?yàn)檫@樣,拋出了前面的UnexpectedRollbackException異常。

spring的事務(wù)是在調(diào)用業(yè)務(wù)方法之前開(kāi)始的,業(yè)務(wù)方法執(zhí)行完畢之后才執(zhí)行commit or rollback,事務(wù)是否執(zhí)行取決于是否拋出runtime異常。如果拋出runtime exception 并在你的業(yè)務(wù)方法中沒(méi)有catch到的話,事務(wù)會(huì)回滾。

在業(yè)務(wù)方法中一般不需要catch異常,如果非要catch一定要手動(dòng)拋出throw new RuntimeException(),否則會(huì)導(dǎo)致事務(wù)失效,數(shù)據(jù)commit造成數(shù)據(jù)不一致,所以有些時(shí)候try catch反倒會(huì)畫(huà)蛇添足。

6、數(shù)據(jù)庫(kù)引擎不支持事務(wù)

這種情況出現(xiàn)的概率并不高,事務(wù)能否生效數(shù)據(jù)庫(kù)引擎是否支持事務(wù)是關(guān)鍵。常用的MySQL數(shù)據(jù)庫(kù)默認(rèn)使用支持事務(wù)的innodb引擎。一旦數(shù)據(jù)庫(kù)引擎切換成不支持事務(wù)的myisam,那事務(wù)就從根本上失效了。

http://www.risenshineclean.com/news/51575.html

相關(guān)文章:

  • wordpress如何開(kāi)發(fā)搜索寧波seo自然優(yōu)化技術(shù)
  • 免費(fèi)做海報(bào)的網(wǎng)站效果好的東莞品牌網(wǎng)站建設(shè)
  • 昆山營(yíng)銷型網(wǎng)站建設(shè)方法模板建站優(yōu)點(diǎn)
  • 產(chǎn)品包裝設(shè)計(jì)網(wǎng)站找誰(shuí)做google瀏覽器下載
  • 壽光專業(yè)做網(wǎng)站的公司天津百度分公司
  • 網(wǎng)站建設(shè)論文的摘要免費(fèi)b站推廣網(wǎng)站入口
  • 校園網(wǎng)站頁(yè)面設(shè)計(jì)杭州排名優(yōu)化公司
  • 關(guān)于網(wǎng)站開(kāi)發(fā)的文獻(xiàn)縱橫seo
  • 企業(yè)網(wǎng)站建設(shè)的實(shí)踐意義外鏈怎么做
  • 如何靠裁圖找到網(wǎng)站中國(guó)最好的營(yíng)銷策劃公司
  • 網(wǎng)站項(xiàng)目建設(shè)申請(qǐng)匯報(bào)大綱網(wǎng)絡(luò)營(yíng)銷推廣方案整合
  • 四網(wǎng)合一網(wǎng)站建設(shè)seo排名點(diǎn)擊軟件推薦
  • 個(gè)人新聞?lì)惥W(wǎng)站模板世界足球排名前100名
  • 體驗(yàn)好的網(wǎng)站陜西省人民政府
  • 互聯(lián)網(wǎng)行業(yè)環(huán)境分析seo博客
  • 網(wǎng)站備案要幕布照新手做銷售怎么開(kāi)發(fā)客戶
  • 建網(wǎng)站公司seo技巧seo排名優(yōu)化
  • 網(wǎng)站建設(shè)賺錢(qián)嗎網(wǎng)站怎么快速排名
  • 昆明做網(wǎng)站建設(shè)價(jià)位50個(gè)市場(chǎng)營(yíng)銷經(jīng)典案例
  • 中信建設(shè)有限責(zé)任公司洪波頁(yè)優(yōu)化軟件
  • 番禺做網(wǎng)站平臺(tái)湖南競(jìng)價(jià)優(yōu)化專業(yè)公司
  • 做房產(chǎn)經(jīng)紀(jì)的那些網(wǎng)站可以進(jìn)客東莞網(wǎng)絡(luò)營(yíng)銷推廣軟件
  • 網(wǎng)站建設(shè)與管理代碼app開(kāi)發(fā)價(jià)格表
  • h5游戲搭建優(yōu)化技術(shù)
  • 品牌網(wǎng)站模板百度指數(shù)如何分析
  • 站長(zhǎng)網(wǎng)站優(yōu)化公司手機(jī)網(wǎng)站建設(shè)價(jià)格
  • wordpress仿站難嗎廣東互聯(lián)網(wǎng)網(wǎng)絡(luò)營(yíng)銷推廣
  • 網(wǎng)站建設(shè)宗旨是什么口碑營(yíng)銷公司
  • 科技公司企業(yè)網(wǎng)站建設(shè)做一個(gè)企業(yè)網(wǎng)站大概需要多少錢(qián)
  • 營(yíng)銷型網(wǎng)站建設(shè)極速建站廣州網(wǎng)絡(luò)seo公司