Spring MVC 中使用AOP 进行事务管理--XML配置实现
1.今天寫一篇使用AOP進行事務(wù)管理的示例,關(guān)于事務(wù)首先需要了解以下幾點
(1)事務(wù)的特性
- 原子性(Atomicity):事務(wù)是一個原子操作,由一系列動作組成。事務(wù)的原子性確保動作要么全部完成,要么完全不起作用。
- 一致性(Consistency):一旦事務(wù)完成(不管成功還是失敗),系統(tǒng)必須確保它所建模的業(yè)務(wù)處于一致的狀態(tài),而不會是部分完成部分失敗。在現(xiàn)實中的數(shù)據(jù)不應(yīng)該被破壞。
- 隔離性(Isolation):可能有許多事務(wù)會同時處理相同的數(shù)據(jù),因此每個事務(wù)都應(yīng)該與其他事務(wù)隔離開來,防止數(shù)據(jù)損壞。
- 持久性(Durability):一旦事務(wù)完成,無論發(fā)生什么系統(tǒng)錯誤,它的結(jié)果都不應(yīng)該受到影響,這樣就能從任何系統(tǒng)崩潰中恢復(fù)過來。通常情況下,事務(wù)的結(jié)果被寫到持久化存儲器中。
(2)事務(wù)的傳播行為
事務(wù)的第一個方面是傳播行為(propagation behavior)。當(dāng)事務(wù)方法被另一個事務(wù)方法調(diào)用時,必須指定事務(wù)應(yīng)該如何傳播。
| PROPAGATION_REQUIRED | 表示當(dāng)前方法必須運行在事務(wù)中。如果當(dāng)前事務(wù)存在,方法將會在該事務(wù)中運行。否則,會啟動一個新的事務(wù) |
| PROPAGATION_SUPPORTS | 表示當(dāng)前方法不需要事務(wù)上下文,但是如果存在當(dāng)前事務(wù)的話,那么該方法會在這個事務(wù)中運行 |
| PROPAGATION_MANDATORY | 表示該方法必須在事務(wù)中運行,如果當(dāng)前事務(wù)不存在,則會拋出一個異常 |
| PROPAGATION_REQUIRED_NEW | 表示當(dāng)前方法必須運行在它自己的事務(wù)中。一個新的事務(wù)將被啟動。如果存在當(dāng)前事務(wù),在該方法執(zhí)行期間,當(dāng)前事務(wù)會被掛起。如果使用JTATransactionManager的話,則需要訪問TransactionManager |
| PROPAGATION_NOT_SUPPORTED | 表示該方法不應(yīng)該運行在事務(wù)中。如果存在當(dāng)前事務(wù),在該方法運行期間,當(dāng)前事務(wù)將被掛起。如果使用JTATransactionManager的話,則需要訪問TransactionManager |
| PROPAGATION_NEVER | 表示當(dāng)前方法不應(yīng)該運行在事務(wù)上下文中。如果當(dāng)前正有一個事務(wù)在運行,則會拋出異常 |
| PROPAGATION_NESTED | 表示如果當(dāng)前已經(jīng)存在一個事務(wù),那么該方法將會在嵌套事務(wù)中運行。嵌套的事務(wù)可以獨立于當(dāng)前事務(wù)進行單獨地提交或回滾。如果當(dāng)前事務(wù)不存在,那么其行為與PROPAGATION_REQUIRED一樣。注意各廠商對這種傳播行為的支持是有所差異的。可以參考資源管理器的文檔來確認它們是否支持嵌套事務(wù) |
(3)事務(wù)的隔離級別
? 事務(wù)的第二個維度就是隔離級別(isolation level)。隔離級別定義了一個事務(wù)可能受其他并發(fā)事務(wù)影響的程度
- 臟讀(Dirty reads)——臟讀發(fā)生在一個事務(wù)讀取了另一個事務(wù)改寫但尚未提交的數(shù)據(jù)時。如果改寫在稍后被回滾了,那么第一個事務(wù)獲取的數(shù)據(jù)就是無效的。
- 不可重復(fù)讀(Nonrepeatable read)——不可重復(fù)讀發(fā)生在一個事務(wù)執(zhí)行相同的查詢兩次或兩次以上,但是每次都得到不同的數(shù)據(jù)時。這通常是因為另一個并發(fā)事務(wù)在兩次查詢期間進行了更新。
- 幻讀(Phantom read)——幻讀與不可重復(fù)讀類似。它發(fā)生在一個事務(wù)(T1)讀取了幾行數(shù)據(jù),接著另一個并發(fā)事務(wù)(T2)插入了一些數(shù)據(jù)時。在隨后的查詢中,第一個事務(wù)(T1)就會發(fā)現(xiàn)多了一些原本不存在的記錄。
| ISOLATION_DEFAULT | 使用后端數(shù)據(jù)庫默認的隔離級別 |
| ISOLATION_READ_UNCOMMITTED | 最低的隔離級別,允許讀取尚未提交的數(shù)據(jù)變更,可能會導(dǎo)致臟讀、幻讀或不可重復(fù)讀 |
| ISOLATION_READ_COMMITTED | 允許讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù),可以阻止臟讀,但是幻讀或不可重復(fù)讀仍有可能發(fā)生 |
| ISOLATION_REPEATABLE_READ | 對同一字段的多次讀取結(jié)果都是一致的,除非數(shù)據(jù)是被本身事務(wù)自己所修改,可以阻止臟讀和不可重復(fù)讀,但幻讀仍有可能發(fā)生 |
| ISOLATION_SERIALIZABLE | 最高的隔離級別,完全服從ACID的隔離級別,確保阻止臟讀、不可重復(fù)讀以及幻讀,也是最慢的事務(wù)隔離級別,因為它通常是通過完全鎖定事務(wù)相關(guān)的數(shù)據(jù)庫表來實現(xiàn)的 |
2.事務(wù)管理有編程式事務(wù)管理和聲明式事務(wù)管理。AOP就是聲明式事務(wù)管理,使用aop實現(xiàn)事務(wù)管理有兩種實現(xiàn)方式,一種是xml配置式,一種是注解式。推薦使用的xml配置式,因為方便,一次配置即可對相應(yīng)包下的所有方法生效,不用再對每個方法加注解。但是注解式使用更加靈活。
實現(xiàn)方式只需要對在spring 配置文件進行相應(yīng)的配置即可。注意頭文件增加相應(yīng)支持。
這是頭文件
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">這是事務(wù)管理相關(guān)配置
<!-- 配置數(shù)據(jù)源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.user}"/><property name="password" value="${jdbc.password}"/></bean><!-- 配置事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 配置事務(wù)通知屬性 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 定義事務(wù)傳播屬性 --> <tx:attributes> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="edit*" propagation="REQUIRED" /> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="new*" propagation="REQUIRED" /> <tx:method name="set*" propagation="REQUIRED" /> <tx:method name="remove*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="change*" propagation="REQUIRED" /> <tx:method name="get*" propagation="REQUIRED" read-only="true" /> <tx:method name="find*" propagation="REQUIRED" read-only="true" /> <tx:method name="load*" propagation="REQUIRED" read-only="true" /> <tx:method name="*" propagation="REQUIRED" read-only="true" /> </tx:attributes> </tx:advice> <!-- 配置事務(wù)切面 --> <aop:config> <aop:pointcut id="serviceOperation" expression="execution(* com.lzl.sss.service..*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" /> </aop:config>關(guān)于事務(wù)管理器我用的是JDBC事務(wù) 管理器,當(dāng)然還有其他的比如
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /> </bean><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean>分別是Hibernate和JPA(Java持久化API事務(wù))的事務(wù)管理器。
上面的切點表達式即可對services包及其子包下的方法進行事務(wù)管理。
3.實現(xiàn)效果
?可以看到有一條數(shù)據(jù)被回滾了。?
?
?
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/li-zhi-long/p/9396320.html
總結(jié)
以上是生活随笔為你收集整理的Spring MVC 中使用AOP 进行事务管理--XML配置实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Log4net 列
- 下一篇: win7通过easyBCD引导ubunt