javascript
Spring入门5.事务管理机制
Spring入門5.事務管理機制 20131126
?
代碼下載 :?鏈接: http://pan.baidu.com/s/1kYc6c 密碼: 233t
回顧之前的知識,Spring 最為核心的兩個部分IoC和AOP,我們已經學習過了,其中IoC是Spring的基礎核心,AOP是建立在IoC之上的,難點是AOP的理解和配置方式。其實AOP編程是一種編程模型,他是站在動態的角度思考程序的運行過程。Spring本身通過IoC容器實現了AOP的思想,但是AspectJ是一種更加專業的主流的AOP編程思想的實現,他站在Java代碼級別上去實現了AOP的編程思想,Spring借鑒了AspectJ的AOP,將他整合在Spring中,使用注解的方式于AspectJ的融合。
???????? 這一節學習Spring中的事務管理:對于事務的理解就是整個操作時原子性的,要么全部做完,要么一點也不做。Spring對于事務處理有著良好的支持,Spring不僅提供了和底層事務員源無關的事物抽象,還提供了聲明式事務,這樣使代碼開發人員從事務處理的底層代碼中解脫出來,專注于業務的處理過程
1.Spring事務策略
???????? JavaEE中事務策略有全局事務和局部事務。全局事務一般由應用服務器管理,需要底層應用服務器的JTA支持,EJB事務就是建立在JTA的基礎之上,而JTA又需要通過JNDI獲取,這樣就意味著無論用戶的應用是跨多個事務性資源的使用還是單一的事物性資源的使用,EJB都要求使用全局事務加以處理,這樣基于EJB的事務就無法脫離應用服務器的環境。
???????? 局部事務是基于單一事務性資源的,通常和底層的持久化技術有關,比如:當采取JDBC時,需要使用Connection對象操作事務;當使用Hibernate持久化技術的是偶,就需要使用session對象操作事務。當使用局部事務的時候,應用服務器不需要參與事務管理的,因此不保證擴多個事務性資源的事物的正確性,但是絕大多數的事物是基于單一事務性資源,只有很少的應用需要使用到多事務性資源的JTA事務。
???????? 在單一事務性資源的情況之下,Spring直接使用底層的數據源管理事務。在面對多個事務性資源的時候,Spring會尋求JavaEE應用服務器的支持,通過引用服務器的JNDI資源完成JTA事務。(當然也可以脫離JavaEE應用服務器的支持使用JTA事務,比如使用JOTM項目,Spring也可以完成JTA的配置)
1.1PlatformTransactionManager
???????? Spring的事務策略是通過PlatformTransactionManager接口來體現的,該接口是Spring事務策略的核心,他根據TransactionDefinition提供的事務屬性配置信息創建事務,并使用TransactionStatus來描述事務激活的狀態。
???????? 在PlatformTransactionManager接口中定義的方法,沒有雨JNDI綁定,可以向Spring普通的bean一樣對待PlatformTransactionManager的實現類,接口方法如下:
Transaction getTransaction(TransactionDefinition def);根據事務定義信息從事務環境中返回一個已經存在的事務,或者是創建一個新的事務,并且使用TransactionStatus來描述這個事務的狀態。
void commit(TransactionStatus status);根據事務的狀態提交事務,如果事務已經被標識為rollback-only,該方法將執行一個回滾事務的操作。
void rollback(TransactionStatus status);將事務回滾,當commit方法拋出異常的時候,rollback方法將會被隱式的調用,回滾事務。
???????? 更進一步,Spring會將事務的管理委托給底層的持久化實現框架完成,因此Spring為不同的持久化框架提供了PlatformTransactionManager接口的實現類:
org.springframework.orm.jpa.JpaTransactionManager: 使用JPA進行持久化,使用這個事務管理器;
org.springframework.orm.hibernate3.HibernateTransactionManager:使用的是Hibernate3進行持久化,使用這一個事務管理器
org.springframework.jdbc.datasource.DataSourceTransactionManager使用Spring JDBC或者是iBatis等數據源的持久化技術,使用這一個事務管理器
org.springframework.orm.toplink.ToplinkTransactionManager: 使用Toplink進行持久化的時候使用
org.springframework.transaction.jta.JtaTransactionManager:具有多個數據源的全局事務使用
???????? 這樣就可以通過Spring提供的高級抽象對不同種類的事物實現相同方式的代理,而不必關心具體的實現。
1.2TransactionDefinition
???????? TransactionDefinition定義的Spring兼容的事務屬性,這些屬性對于事務管理的控制的若干方法進行配置沒比如事務隔離級別、事務傳播、事務超時和制度狀態(都是新的名詞,不要害怕,我也是第一次接觸這些名詞)
???????? 事務隔離級別:當前的事物和其他事物的隔離程度。比如當前事務能否看到其他事物未提交的數據。TransactionDefinition定義的事務隔離級別:
ISOLATION_READ_UNCOMMITED:讀未提交,一個事務在執行過程中可以看到其他事物沒有提交的新插入記錄,而且能夠看到其他事務,沒有提交對已有記錄的更新。
ISOLATION_READ_COMMITED: 讀已提交
ISOLATION_REPEATABLE_READ:可重復讀,一個事務在執行過程中可以看到其他事務已經提交的新插入記錄,但是不能夠看到其他事務對已有記錄的更新。
ISOLATION_SERIALIZABLE:序列化讀,一個事務只可以操作在該事務提交之間已經提交的數據,并且可以在該事務中操作這些數據。
ISOLATION_DEFAULT:表示使用底層數據庫默認的隔離級別。
???????? 事務傳播:一般在事務中執行的代碼都會在當前事務中運行。但是如果一個事務上下文已經存在,有幾個選項可以指定該事務性方法的執行行為。比如可以簡單地在現有事務上下文中運行或者掛起現有事務,創建一個新的事務。
???????? Spring在TransactionDefinition接口中規定了7中類型的事務傳播行為,它規定了事務方法和事務方法發生嵌套調用時事務如何進行傳播:
PROPAGATION_REQUIRED
PROPAGATION_SUPPORTS:
PROPAGATION_MANDATONRY
PROPAGATION_REQUIRES_NEW
PROPAGATION_NOT_SUPPORTED
PROPAGATION_NEVER
PROPAGATION_NESTED
???????? 通過TransactionDefinition接口中的getPropagationBehavior()方法可以獲得事務的傳播性
???????? 事務超時:表示事務在超時之前可以運行多久,也就是事務的最長續航時間。如果事務一直處于未提交或者是回滾狀態,那么當超出時間的時候,事務將會自動回滾事務。通過TransactionDefinition接口中的getTimeout()獲得事務的超時時間。
???????? 只讀狀態:只讀事務是不會修改任何數據的,只讀事務對于優化十分重要,通過TransactionDefinition的isReadOnly()接口判斷一個事務是否是只讀的事務。
1.3TransactionStatus
???????? 代表一個事務的運行狀態。事務管理器通過該接口獲得事務的運行期狀態,也可以通過該接口間接的回滾事務,他相比于在拋出異常在回滾事務的方式更加具有可控性。
???????? boolean hasSavePoint()
???????? boolean isNewTransaction()
???????? boolean isCompleted(); 已經回滾或者是提交
???????? boolean isRollbackOnly();
???????? void setRolbackOnly()
???????? 一點提醒:實際開發中對于PlatformTransactionManager、TransactionDefinition、TransactionStatus三個接口,開發者不會直接使用,而是通過配置的方式使用Spring提供的子類。了解這些知識點有利于幫助我們理解Spring中的事務機制。
?
2.使用XML的方式配置聲明式事務
???????? 事務管理的方式有兩種:編程式和聲明式。編程式事務管理需要在代碼中手動編寫和事務相關的操作代碼,而對于聲明式事務則無需再Java程序中編寫任何和事務相關的代碼。
???????? 大多數的Spring選擇的是聲明式的事物管理功能,這種方式對于代碼的侵入性比較小,可以讓事務管理的邏輯完全從業務邏輯中移除,比較輕量級。Spring聲明式事務管理是通過Spring AOP實現的,通過事務的聲明性信息,Spring負責將事務管理Advice邏輯動態織入到業務方法對應的連接點上。這些邏輯包括獲取線程綁定資源、開始事務、提交回滾事務,進行異常轉換等。
例子:以JDBC數據源為例
2.1配置數據源以及事務管理對象
???????? 使用XML配置DBCP數據源,同時配置Spring提供的事物管理對象。
<!-- 數據源配置信息 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
??? <property name="driverClassName"? ? value="com.mysql.jdbc.Driver"/>
??? <property name="url"??????????????? value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8"/>
??? <property name="username"?????????? value="root"/>
??? <property name="password"?????????? value="221256"/>
??? <property name="initialSize"??????? value="5"/>
??? <property name="maxActive"????????? value="100"/>
??? <property name="maxIdel"??????????? value="30"/>
??? <property name="maxWait"??????????? value="1000"/>
</bean>
?
<!-- 事務管理器配置信息 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
??? <property name="dataSource"???????? ref="dataSource"/>
</bean>
2.2配置事務的Advice
??? 在Spring中事務的Advice是有<tx:advice/>元素進行配置的。在該元素中,可以針對每一個方法或者是每一批方法配置事務的Advice
<beans
??? xmlns="http://www.springframework.org/schema/beans"
??? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
??? xmlns:aop="http://www.springframework.org/schema/aop"
??? xmlns:tx="http://www.springframework.org/schema/tx"
??? xsi:schemaLocation="
??????? http://www.springframework.org/schema/beans
??????? http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
??????? http://www.springframework.org/schema/aop
??????? http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
??????? http://www.springframework.org/schema/tx
??????? http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
??????? default-lazy-init="true">
<tx:advice id="txAdvice" transaction-manager="txManager">
??????? <!-- 事務屬性定義 -->
??????? <tx:attributes>
??????????? <tx:method name="get*" read-only="true"/>
??????????? <tx:method name="add*" rollback-for="Exception"/>
??????????? <tx:method name="update*" />
??????????? <tx:method name="del*"/>
??????? </tx:attributes>
??? </tx:advice>
?
??? 在上述配置中,首先是引入命名空間的聲明,然后使用<tx:advice>元素配置事務的Advice,在<tx:advice>中使用<tx:attributes>元素通過配置<tx:method/>子元素為一批方法指定所需要的語義,包括事務傳播屬性、事務隔離級別、事務超時等等。
??? <tx:advice>中id是事務Advice的標識;transaction-manager是指定已經配置的事物管理器,如果事務管理器的id是transactionManager,則可以省略。配置<tx:advice>元素的重點是配置<tx:method>子元素,拓為一批方法指定了所需的事務原語,比如事務傳播屬性、事務隔離屬性、事務超時屬性、只讀屬性、對于指定異常回滾和指定異常不回滾,下面是<tx:method>的各種屬性:
??? name 可以使用通配符
??? propagation 默認是REQUIRED,可選的值有REQUIRED SUPPRTS MANDATORY REQUIRES_NEW??? NOT_SUPPORTED NEVER NESTED 表示的是傳播
??? isolation: 默認是DEFAULT 表示事務的隔離級別
??? timeout defalur 是-1,單位秒,表示永不超時
??? read-only: default false 只讀事務,便于查詢優化
??? rollback-for: 所有運行期異常回滾,可以有多個Exception,逗號隔開
??? no-rollback-for: 所有檢查性異常不回滾
2.3配置事務增強切面
??? 通過事務Advice Aspect的配置實現方法級別的事務管理
??? <!-- 通過AOP配置事務增強切面 -->
??? <aop:config>
??????? <aop:pointcut expression="execution(* com.yang.service.USerService.*(..))" id="allMethods"/>
??????? <aop:advisor advice-ref="txAdvice" pointcut-ref="allMethods"/>
??? </aop:config>
??? 上述配置,配置了一個id是allMethods的切入點,匹配UserService下面的所有方法,然后使用一個<aop:advice>把切入點和事務增強txAdvice綁定在一起,當allMethods執行的時候,txAdvice定義的增強將被織入特定的連接點。
??? 其實在標準的AOP中是沒有Advisor的概念的,Advisor實際上是表示的切面的概念,它同時包含橫切代碼和連接點信息。<aop:advisor>的作用就是講增強和切入點綁定在一起,保證增強所包含的很企鵝邏輯在特定的連接點被織入。
2.4運行結果
??? 使用事務機制,向數據庫中插入相同的兩行記錄,這樣就會存在兩行數據都無法出入導數據庫中,體現事務的原子性操作。
UserDao.java
public interface UserDao {
??? public void add();
}
UserDaoImpl.java
public class UserDaoImpl implements UserDao {
?
??? DataSource dataSource;// 數據庫連接接口,用于初始化JdbcTemplate,他是Spring中的JDBC的核心類之一
??? public DataSource getDataSource(){
??????? return this.dataSource;
??? }
??? public void setDataSource(DataSource dataSource){
??????? this.dataSource = dataSource;
??? }
??? @Override
??? public void add() {
??????? // 因為該函數是基于事務機制執行的,所以執行的時候會發生錯誤,兩條記錄都不會插入到數據庫中。
??????? JdbcTemplate template = new JdbcTemplate(this.dataSource);
??????? template.execute("insert into user (id, username,password) values ( 3, 'yangtengfei','34567')");
??????? template.execute("insert into user (id, username,password) values ( 4, 'yangtengfei','456789')");? ???
??? }
}
同時需要在applicationContext.xml配置文件中使用IoC的機制生命userDao和userService的Bean:
<!-- 配置UserService Class -->
??? <bean id="userDao" class="com.yang.dao.impl.UserDaoImpl">
??????? <property name="dataSource" ref="dataSource"/>
??? </bean>
???
??? <bean id="userService" class="com.yang.service.impl.UserServiceImpl">
??????? <property name="userDao" ref="userDao"/>
??? </bean>
代碼整理:
UserDao.java//數據庫的接口
UserDaoImpl.java//數據庫接口實現類
UserService.java//用戶的服務接口
UserServiceImpl.java//用戶Service接口的實現類
applicationContext.xml//配置文件
TestMain.java//項目入口函數
同時需要添加JAR包的支持:Spring3 common mysql AspectJ的包。
最重要的是配置文件: applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
??? xmlns="http://www.springframework.org/schema/beans"
??? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
??? xmlns:aop="http://www.springframework.org/schema/aop"
??? xmlns:tx="http://www.springframework.org/schema/tx"
??? xsi:schemaLocation="
??????? http://www.springframework.org/schema/beans
??????? http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
??????? http://www.springframework.org/schema/aop
??????? http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
??????? http://www.springframework.org/schema/tx
??????? http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
??????? default-lazy-init="true">
??? <aop:aspectj-autoproxy/>???
???
??? <!-- 數據源配置信息 -->
??? <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
??????? <property name="driverClassName"? ? value="com.mysql.jdbc.Driver"/>
??????? <property name="url"??????????????? value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8"/>
??????? <property name="username"?????????? value="root"/>
??????? <property name="password"?????????? value="221256"/>
??????? <property name="initialSize"??????? value="5"/>
??????? <property name="maxActive"????????? value="100"/>
??????? <property name="maxIdle"??????????? value="30"/>
??????? <property name="maxWait"??????????? value="1000"/>
??? </bean>
???
??? <!-- 配置UserService Class -->
??? <bean id="userDao" class="com.yang.dao.impl.UserDaoImpl">
??????? <property name="dataSource" ref="dataSource"/>
??? </bean>
???
??? <bean id="userService" class="com.yang.service.impl.UserServiceImpl">
??????? <property name="userDao" ref="userDao"/>
??? </bean>
???
??? <!-- 事務管理器配置信息 -->
??? <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
??????? <property name="dataSource"???????? ref="dataSource"/>
??? </bean>
???
??? <tx:advice id="txAdvice" transaction-manager="txManager">
??????? <!-- 事務屬性定義 -->
??????? <tx:attributes>
??????????? <tx:method name="get*" read-only="true"/>
??????????? <tx:method name="add*" rollback-for="Exception"/>
??????????? <tx:method name="update*" />
??????????? <tx:method name="del*"/>
??????? </tx:attributes>
??? </tx:advice>
???
??? <!-- 通過AOP配置事務增強切面 -->
??? <aop:config>
??????? <aop:pointcut expression="execution(* com.yang.service.UserService.*(..))" id="allMethods"/>
??????? <aop:advisor advice-ref="txAdvice" pointcut-ref="allMethods"/>
??? </aop:config>
</beans>
?
YangTengfei
2013.11.27
?
轉載于:https://www.cnblogs.com/hbhzsysutengfei/p/3473193.html
總結
以上是生活随笔為你收集整理的Spring入门5.事务管理机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新浪微博说说html,说说新浪微博
- 下一篇: struts2:JSP页面及Action