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ù)管理模型,你可以寫(xiě)一次代碼,然后在不同的環(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)寫(xiě)錯(cuò)了
2. 查找Controller掃描部分配置是否正確
2. 查找Controller掃描部分配置是否正確
但是這兩點(diǎn)我都查了,還是事務(wù)沒(méi)有回滾,這個(gè)時(shí)候我沒(méi)辦法了,只能動(dòng)用終極武器了:查看源碼,開(kāi)始debug程序,發(fā)現(xiàn)進(jìn)入到了事務(wù),并且出現(xiàn)了異常,捕獲后進(jìn)入到了回滾程序,但是數(shù)據(jù)庫(kù)卻沒(méi)有回滾,為了避免Spring自己的AbstractPlatformTransactionManager的干擾,我自己定制了一個(gè)事務(wù)管理類(lèi)并繼承配置文件中的DataSourceTransactionManager類(lèi),這樣可以清楚的看到程序的運(yùn)行軌跡,繼續(xù)DEBUG,還是出現(xiàn)了異常,捕獲后進(jìn)入到了回滾程序,但是數(shù)據(jù)庫(kù)卻沒(méi)有回滾,此刻我開(kāi)始懷疑MySQL數(shù)據(jù)庫(kù)的事務(wù)支持功能了,于是網(wǎng)上查找MySQL對(duì)事務(wù)的支持,發(fā)現(xiàn)MySQL4.0以后可以支持事務(wù),但是MySql的數(shù)據(jù)表分為兩類(lèi),一類(lèi)是傳統(tǒng)的數(shù)據(jù)表,另一類(lèi)則是支持事務(wù)的數(shù)據(jù)表。支持事務(wù)的數(shù)據(jù)表分為兩種:InnoDB和BerkeleyDB
使用一下命令:show create table *** 查看我的數(shù)據(jù)庫(kù)表的屬性才發(fā)現(xiàn)我的表原來(lái)是傳統(tǒng)類(lèi)型的表,于是我使用navicat更改了表的類(lèi)型為:InnoDB,然后運(yùn)行程序發(fā)現(xiàn)事務(wù)回滾了
到此SpringMVC聲明式事務(wù)管理配置完成,并運(yùn)行正確
相關(guān)文章
Spring Boot修改內(nèi)置Tomcat默認(rèn)端口號(hào)的示例
本篇文章主要介紹了Spring Boot修改內(nèi)置Tomcat端口號(hào)的示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Springboot使用MybatisPlus實(shí)現(xiàn)mysql樂(lè)觀鎖
MySQL中的樂(lè)觀鎖(Optimistic?Locking)是一種并發(fā)控制策略,本文將使用Springboot和MybatisPlus實(shí)現(xiàn)MySQL中的樂(lè)觀鎖,需要的可以參考下2024-12-12
Maven項(xiàng)目打包成可執(zhí)行Jar文件步驟解析
這篇文章主要介紹了Maven項(xiàng)目如何打包成可執(zhí)行Jar文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
Java中JSON字符串進(jìn)行各種轉(zhuǎn)換的方法小結(jié)
Gson和Hutool的JSONUtil都是常用的用于處理JSON數(shù)據(jù)的工具庫(kù),它們提供了簡(jiǎn)單易用的API來(lái)進(jìn)行JSON字符串的解析、轉(zhuǎn)換和操作,下面就跟隨小編一起學(xué)習(xí)一下如果使用他們實(shí)現(xiàn)JSON字符串的各種轉(zhuǎn)換吧2024-01-01

