SpringMVC+MyBatis聲明式事務(wù)管理
更新時(shí)間:2015年08月09日 15:14:37 投稿:hebedich
在最近的一個(gè)項(xiàng)目中,采用springMVC、mybatis,MySQL、tomcat,事務(wù)管理對(duì)于企業(yè)應(yīng)用來(lái)說(shuō)是至關(guān)重要的,即使出現(xiàn)異常情況,它也可以保證數(shù)據(jù)的一致性。Spring Framework對(duì)事務(wù)管理提供了一致的抽象,
采用的基本搭建環(huán)境:SpringMVC、MyBatis、MySQL、tomcat
Spring事務(wù)管理分解了傳統(tǒng)的全局事務(wù)管理和本地事務(wù)管理的劣勢(shì),使得在任何環(huán)境中都可以使用統(tǒng)一的事務(wù)管理模型,你可以寫一次代碼,然后在不同的環(huán)境從你的代碼里面配置不同的事務(wù)管理策略,Spring提供兩種事務(wù)管理策略:一種是聲明式事務(wù)管理策略,另一種是編程式事務(wù)管理策略,這里主要介紹聲明式事務(wù)管理策略
由于采用的是SpringMVC、 MyBatis,故統(tǒng)一采用了標(biāo)注來(lái)聲明Service、Controller
由于服務(wù)器啟動(dòng)時(shí)的加載配置文件的順序?yàn)閣eb.xml---root-context.xml(Spring的配置文件)---servlet-context.xml(SpringMVC的配置文件),由于root-context.xml配置文件中Controller會(huì)先進(jìn)行掃描裝配,但是此時(shí)service還沒(méi)有進(jìn)行事務(wù)增強(qiáng)處理,得到的將是原樣的Service(沒(méi)有經(jīng)過(guò)事務(wù)加強(qiáng)處理,故而沒(méi)有事務(wù)處理能力),所以我們必須在root-context.xml中不掃描Controller,配置如下:
由于服務(wù)器啟動(dòng)時(shí)的加載配置文件的順序?yàn)閣eb.xml---root-context.xml(Spring的配置文件)---servlet-context.xml(SpringMVC的配置文件),由于root-context.xml配置文件中Controller會(huì)先進(jìn)行掃描裝配,但是此時(shí)service還沒(méi)有進(jìn)行事務(wù)增強(qiáng)處理,得到的將是原樣的Service(沒(méi)有經(jīng)過(guò)事務(wù)加強(qiáng)處理,故而沒(méi)有事務(wù)處理能力),所以我們必須在root-context.xml中不掃描Controller,配置如下:
<!-- 自動(dòng)掃描組件,這里要把controler下面的 controller去除,他們是在spring3-servlet.xml中配置的,如果不去除會(huì)影響事務(wù)管理的。 --> <context:component-scan base-package="com.sence"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> .</context:component-scan> <!-- 自動(dòng)掃描組件,這里要把controler下面的 controller去除,他們是在spring3-servlet.xml中配置的,如果不去除會(huì)影響事務(wù)管理的。 --> <context:component-scan base-package="com.sence"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan>
在servlet-context.xml中掃描Controller同時(shí)不掃描Service,配置如下:
<!-- 掃描所有的controller 但是不掃描service--> <context:component-scan base-package="com.sence"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" /> </context:component-scan> <!-- 掃描所有的controller 但是不掃描service--> <context:component-scan base-package="com.sence"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" /> </context:component-scan>
下面就可以進(jìn)行配置聲明式事務(wù)管理了,配置如下:
<!-- transaction manager, use DataSourceTransactionManager --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- spring declarative transaction management --> <aop:config> <aop:pointcut id="fooServiceMethods" expression="execution(* com.sence.*.service.impl.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceMethods"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="find*" read-only="true"/> <tx:method name="load*" read-only="true"/> <tx:method name="*" rollback-for="CustomException"/> </tx:attributes> </tx:advice> <!-- transaction manager, use DataSourceTransactionManager --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- spring declarative transaction management --> <aop:config> <aop:pointcut id="fooServiceMethods" expression="execution(* com.sence.*.service.impl.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceMethods"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="find*" read-only="true"/> <tx:method name="load*" read-only="true"/> <tx:method name="*" rollback-for="CustomException"/> </tx:attributes> </tx:advice>
到此我的配置完成了,但是經(jīng)過(guò)我的測(cè)試,當(dāng)我往MySQL數(shù)據(jù)庫(kù)表批量增加對(duì)象時(shí),當(dāng)其中一個(gè)對(duì)象出現(xiàn)錯(cuò)誤,拋出CustomException事務(wù)卻不回滾,這個(gè)真是令人頭疼,于是我繼續(xù)查找,步驟如下:
1. 查找是否聲明式事務(wù)管理有誤,如切入點(diǎn)寫錯(cuò)了
2. 查找Controller掃描部分配置是否正確
2. 查找Controller掃描部分配置是否正確
但是這兩點(diǎn)我都查了,還是事務(wù)沒(méi)有回滾,這個(gè)時(shí)候我沒(méi)辦法了,只能動(dòng)用終極武器了:查看源碼,開始debug程序,發(fā)現(xiàn)進(jìn)入到了事務(wù),并且出現(xiàn)了異常,捕獲后進(jìn)入到了回滾程序,但是數(shù)據(jù)庫(kù)卻沒(méi)有回滾,為了避免Spring自己的AbstractPlatformTransactionManager的干擾,我自己定制了一個(gè)事務(wù)管理類并繼承配置文件中的DataSourceTransactionManager類,這樣可以清楚的看到程序的運(yùn)行軌跡,繼續(xù)DEBUG,還是出現(xiàn)了異常,捕獲后進(jìn)入到了回滾程序,但是數(shù)據(jù)庫(kù)卻沒(méi)有回滾,此刻我開始懷疑MySQL數(shù)據(jù)庫(kù)的事務(wù)支持功能了,于是網(wǎng)上查找MySQL對(duì)事務(wù)的支持,發(fā)現(xiàn)MySQL4.0以后可以支持事務(wù),但是MySql的數(shù)據(jù)表分為兩類,一類是傳統(tǒng)的數(shù)據(jù)表,另一類則是支持事務(wù)的數(shù)據(jù)表。支持事務(wù)的數(shù)據(jù)表分為兩種:InnoDB和BerkeleyDB
使用一下命令:show create table *** 查看我的數(shù)據(jù)庫(kù)表的屬性才發(fā)現(xiàn)我的表原來(lái)是傳統(tǒng)類型的表,于是我使用navicat更改了表的類型為:InnoDB,然后運(yùn)行程序發(fā)現(xiàn)事務(wù)回滾了
到此SpringMVC聲明式事務(wù)管理配置完成,并運(yùn)行正確
相關(guān)文章
Spring?Boot超大文件上傳實(shí)現(xiàn)秒傳功能
這篇文章主要介紹了Spring?Boot超大文件上傳實(shí)現(xiàn)秒傳功能,在實(shí)現(xiàn)分片上傳的過(guò)程,需要前端和后端配合,比如前后端的上傳塊號(hào)的文件大小,前后端必須得要一致,否則上傳就會(huì)有問(wèn)題,需要的朋友可以參考下2022-12-12java string 轉(zhuǎn)date方法如何實(shí)現(xiàn)
在開發(fā)應(yīng)用中經(jīng)常會(huì)使用到j(luò)ava string 轉(zhuǎn)date這種不是很常見的做法,本文將以此問(wèn)題提供詳細(xì)解決方案,需要了解的朋友可以參考下2012-11-11SpringBoot?DataSource數(shù)據(jù)源實(shí)現(xiàn)自動(dòng)配置流程詳解
這篇文章主要介紹了SpringBoot?DataSource數(shù)據(jù)源實(shí)現(xiàn)自動(dòng)配置流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-10-10My eclipse 端口占用(9360)問(wèn)題解決辦法
這篇文章主要介紹了My eclipse 工程發(fā)布時(shí)出現(xiàn)端口占用問(wèn)題解決辦法的相關(guān)資料,需要的朋友可以參考下2016-12-12springboot 緩存@EnableCaching實(shí)例
這篇文章主要介紹了springboot 緩存@EnableCaching實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11java實(shí)現(xiàn)給圖片加鋪滿的網(wǎng)格式文字水印
這篇文章主要給大家介紹了關(guān)于java實(shí)現(xiàn)給圖片加鋪滿的網(wǎng)格式文字水印的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01Java在ElasticSearch中使用LocalDatetime類型
最近在開發(fā)一個(gè)搜索功能的需求的時(shí)候,遇到了LocalDatetime類型不能保存到ElasticSearch中的問(wèn)題,這篇文章主要介紹了Java在ElasticSearch中使用LocalDatetime類型2023-10-10