欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Spring 說(shuō)明文檔 Chapter 7. 事務(wù)管理

Chapter 7. 事務(wù)管理

7.1. Spring事務(wù)抽象

Spring提供了一致的事務(wù)管理抽象。這個(gè)抽象是Spring最重要的抽象之一, 提供如下的優(yōu)點(diǎn):

  • 提供跨越不同的事務(wù)API,如JTA、JDBC、Hibernate、iBATIS數據庫層 和JDO的一致的編程模型

  • 提供比大多數事務(wù)API更簡(jiǎn)單的,易用的編程式事務(wù)管理API

  • 整合Spring數據訪(fǎng)問(wèn)抽象。

  • 支持Spring聲明式事務(wù)管理

傳統上,J2EE開(kāi)發(fā)者有兩個(gè)事務(wù)管理的選擇: 全局局部事務(wù)。全局事務(wù)由應用服務(wù)器管理,使用JTA。局部 事務(wù)是資源相關(guān)的:例如,一個(gè)和JDBC連接關(guān)聯(lián)的事務(wù)。這個(gè)選擇有深刻的含義。 全局事務(wù)提供和多個(gè)參與事務(wù)的資源(需要指出的是多數應用使用單一參與事務(wù) 的資源)。使用局部事務(wù),應用服務(wù)器不需要參與事務(wù)管理,并且不能幫助確保 跨越多個(gè)資源的正確性。

全局事務(wù)有一個(gè)顯著(zhù)的不利方面,代碼需要使用JTA:一個(gè)笨重的API(部分是 因為它的異常模型)。此外,JTA UserTransaction通常需 要從JNDI獲得,意味著(zhù)我需要同時(shí)使用JNDI和JTA來(lái)使用 JTA。顯然全部使用全局事務(wù)限制了應用代碼的重用性,因為JTA通常只在應用服 務(wù)器的環(huán)境中才能使用。

首選的使用全局事務(wù)的方式是通過(guò)EJB的CMT (容器管理的事務(wù)): 一種形式的 聲明式事務(wù)管理(區別于編程式事務(wù)管理 )。EJB的CMT消除了事務(wù)相關(guān)的JNDI查找的需求,雖然使用EJB本身 肯定需要使用JNDI。它消除大多數――不是全部――書(shū)寫(xiě)Java代碼控制事務(wù)的需求。 顯著(zhù)的不利方面是CMT和JTA以及應用服務(wù)器環(huán)境捆綁在一起,并且只有我們選擇 使用EJB實(shí)現業(yè)務(wù)邏輯時(shí)才能使用,或者至少使用在一個(gè)事務(wù)化EJB的外觀(guān) (Fa?ade)后。EJB有如此多的詬病,當存在可供選擇的聲明式事務(wù)管理時(shí), EJB不是一個(gè)吸引人的建議。

局部事務(wù)容易使用,但也有明顯的不利方面:它們不能跨越多個(gè)參與事務(wù)的資 源使用,并且趨向侵入的編程模型。例如,使用JDBC連接事務(wù)管理的代碼不能使 在全局的JTA事務(wù)中。

Spring解決了這些問(wèn)題。它使應用開(kāi)發(fā)者能夠使用在任何環(huán)境 下使用一致的編程模型。你可以只寫(xiě)一次你的代碼,這些代碼可以從在不同環(huán)境 下的不同事務(wù)管理策略中獲益。Spring同時(shí)提供聲明式和編程式事務(wù)管理。

使用編程式事務(wù)管理,開(kāi)發(fā)者使用Spring事務(wù)抽象,這個(gè)抽象可以使用的任何 底層事務(wù)基礎之上。使用首選的聲明式模型,開(kāi)發(fā)者通常書(shū)寫(xiě)很少的事務(wù)相關(guān)代 碼,因此不依賴(lài)Spring或任何其他事務(wù)API。

7.2. 事務(wù)策略

Spring事務(wù)抽象的關(guān)鍵是事務(wù)策略的概念。

這個(gè)概念由 org.springframework.transaction.PlatformTransactionManager 接口表達,如下:

public interface PlatformTransactionManager {

    TransactionStatus getTransaction(TransactionDefinition definition)
        throws TransactionException;

    
void commit(TransactionStatus status) throws TransactionException;

    
void rollback(TransactionStatus status) throws TransactionException;
}

這首先是一個(gè)SPI接口,雖然它也可以在編碼中使用。注意按照Spring的哲學(xué), 這是一個(gè)接口。因而如果需要它可以很容易地被模擬和 樁化。它也沒(méi)有和一個(gè)查找策略如JNDI捆綁在一起:PlatformTransactionManager 的實(shí)現定義和其他Spring IoC容器中的對象一樣。這個(gè)好處使得即使使用JTA這也 是一個(gè)很有價(jià)值的抽象:事務(wù)代碼可以比直接使用JTA更加容易測試。

繼續Spring哲學(xué),TransactionException是不被檢查的。 低層的事務(wù)失敗幾乎都是一成不變地致命。很少情況下應用程序代碼可以從它們 中恢復,不過(guò)應用開(kāi)發(fā)者依然可以捕獲并處理 TransactionException。

getTransaction()根據一個(gè) TransactionDefinition類(lèi)型參數返回一個(gè) TransactionStatus對象,返回的 TransactionStatus對象可以代表一個(gè)新的或已經(jīng)存在的事 務(wù)(如果在當前調用堆棧有一個(gè)符合條件的事務(wù))。

如同J2EE事務(wù)上下文,一個(gè)TransactionStatus也是和執 行的線(xiàn)程關(guān)聯(lián)的。

TransactionDefinition接口指定:

  • 事務(wù)隔離:當前事務(wù)隔離的程度來(lái)至 于其他的事務(wù)的工作情況。例如,這個(gè)事務(wù)能否看到其他事務(wù)未提交的寫(xiě)數 據?

  • 事務(wù)傳播:通常在一個(gè)事務(wù)中執行的 所有代碼都會(huì )在這個(gè)事務(wù)中運行。但是,如果當一個(gè)事務(wù)上下文已經(jīng)存在時(shí), 一個(gè)事務(wù)方法被執行,有幾個(gè)選項可以指定其行為:例如,簡(jiǎn)單地在現有的 事務(wù)中運行(大多數情況);或者掛起現有事務(wù),創(chuàng )建一個(gè)新的事務(wù)。 Spring提供EJB CMT中熟悉的事務(wù)傳播選項。

  • 事務(wù)超時(shí): 事務(wù)在超時(shí)前能運行多 久(自動(dòng)被底層的事務(wù)基礎設施回滾)。

  • 只讀狀態(tài): 只讀事務(wù)不修改任何數 據。只讀事務(wù)在某些情況下(例如當使用Hibernate時(shí))可能是最佳選擇。

這些設置反映了標準概念。如果需要,請查閱討論事務(wù)隔離層次和其他核心事 務(wù)概念的資源:理解這些概念是使用Spring和其他事務(wù)管理解決方案的基本要素。

TransactionStatus接口為處理事務(wù)的代碼提供一個(gè)簡(jiǎn)單 的控制事務(wù)的執行和查詢(xún)事務(wù)狀態(tài)方法。這個(gè)概念應該是熟悉的,因為它們在所 有的事務(wù)API中是相同的:

public interface TransactionStatus {

    boolean isNewTransaction();

    
void setRollbackOnly();

    boolean isRollbackOnly();
}

但是使用Spring事務(wù)管理時(shí),定義 PlatformTransactionManager的實(shí)現是基本方式。在好的Spring 風(fēng)格中,這個(gè)重要定義使用IoC實(shí)現。

PlatformTransactionManager實(shí)現通常需要了解它們工作 的環(huán)境:JDBC、JTA、Hibernate等等。

下面來(lái)自Spring范例jPetstore中的 dataAccessContext-local.xml的例子展示了一個(gè)局部 PlatformTransactionManager實(shí)現是如何定義的。它將和JDBC一起工作。

我們必須定義JDBC數據源,然后使用DataSourceTransactionManager,提供給 它的一個(gè)數據源引用。

<bean id="dataSource" 
    class
="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    
<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
    
<property name="url"><value>${jdbc.url}</value></property>
    
<property name="username"><value>${jdbc.username}</value></property>
    
<property name="password"><value>${jdbc.password}</value></property>
</bean>

PlatformTransactionManager定義如下:

<bean id="transactionManager" 
    class
="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    
<property name="dataSource"><ref local="dataSource"/></property>
</bean>

如果我們使用JTA,如同范例中dataAccessContext-jta.xml, 我們需要使用容器數據源,通過(guò)JNDI獲得,還需要一個(gè)JtaTransactionManager實(shí) 現,JtaTransactionManager不需要知道數據源,或任何其他指定資源,因為它將 使用容器的全局事務(wù)管理。

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    
<property name="jndiName"><value>jdbc/jpetstore</value></property>
</bean>

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>

我們可以很容易地使用Hibernate局部事務(wù),如同下面Spring PetClinic 范例中的例子展現的一樣。

在這種情況下,我們需要定義一個(gè)Hibernate的LocalSessionFactory,應用程 序將使用它獲得Hibernate Sessions。

數據源bean定義和上面例子類(lèi)似,這里不在羅列(如果這是一個(gè)不需事務(wù)的容 器數據源,Spring而不是容器將管理事務(wù))。

這種情況“transactionManager” bean的類(lèi)型是HibernateTransactionManager。 和DataSourceTransactionManager擁有一個(gè)數據源的引用一樣, HibernateTransactionManager需要一個(gè) SessionFactory的引用。

<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
    
<property name="dataSource"><ref local="dataSource"/></property>
    
<property name="mappingResources">
        
<value>org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml</value>
    
</property>
    
<property name="hibernateProperties">
        
<props>
            
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
        
</props>
    
</property>
</bean>

<bean id="transactionManager" 
    class
="org.springframework.orm.hibernate.HibernateTransactionManager">
    
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>

使用Hibernate和JTA事務(wù)我們可以簡(jiǎn)單地使用JtaTransactionManager, 如同JDBC或任何其他資源策略。

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>

注意這是和任何其他使用JTA配置的其他資源一樣的,因為它們都是全局事務(wù)。

在所有這些情況下,應用程序代碼不需要任何更改。我們可以?xún)H僅更改配置 來(lái)更改事務(wù)方式,甚至這些更改意味這從局部事務(wù)轉換到全局事務(wù)或者相反方向 的轉換。

如果不使用全局事務(wù),你需要采用一個(gè)特定的代碼規范。幸運的這是非常簡(jiǎn)單 的。你需要以一個(gè)特定的方式獲得連接或者session資源,允許相關(guān)的 PlatformTransactionManager實(shí)現跟蹤連接的使用,并且當需要時(shí)應用事務(wù)管理。

例如,如果使用JDBC,你不應該調用一個(gè)數據源的 getConnection()方法,而必須使用Spring的 org.springframework.jdbc.datasource.DataSourceUtils類(lèi),如下:

Connection conn = DataSourceUtils.getConnection(dataSource);

這將提供額外的好處,任何SQLException都被Spring的 CannotGetJdbcConnectionException――Spring的不被檢查 的DataAccessException的類(lèi)層次之一包裝起來(lái)。這給你比 簡(jiǎn)單地從SQLException獲得更多的信息,并且確??鐢祿?庫,甚至跨越不同持久化技術(shù)的可移植性。

這將很好地在沒(méi)有Spring事務(wù)管理的情況下工作,因此無(wú)論使用還是不使用 Spring事務(wù)管理,你都可以使用它。

當然,一旦你使用Spring JDBC支持或Hibernate支持,你將不必使用 DataSourceUtils或其他幫助類(lèi),因為你將比直接使用相關(guān) API更加愉快地使用Spring的抽象。例如,如果你使用Spring JdbcTemplate或 jdbc.object包來(lái)簡(jiǎn)化使用JDBC,正確的數據庫連接將自動(dòng)取得,你不需要書(shū)寫(xiě) 任何特定代碼。

7.3. 編程式事務(wù)管理

Spring提供兩種方式的編程式事務(wù)管理

  • 使用TransactionTemplate

  • 直接使用PlatformTransactionManager一個(gè)實(shí)現

我們通常推薦使用第一種方式。

第二種方式類(lèi)似使用JTA UserTransaction API (雖然異常處理少一點(diǎn)麻煩)。

7.3.1. 使用TransactionTemplate

TransactionTemplate采用和其他Spring模板 JdbcTemplateHibernateTemplate一樣的方法。它使用回調方法,把應用 程序代碼從處理取得和釋放資源中解脫出來(lái)(不再有try/catch/finally)。如同 其他模板,TransactionTemplate是線(xiàn)程安全的。

必須在事務(wù)上下文中執行的應用代碼看起來(lái)像這樣,注意使用 TransactionCallback可以返回一個(gè)值:

Object result = tt.execute(new TransactionCallback() {
    
public Object doInTransaction(TransactionStatus status) {
        updateOperation1();
        
return resultOfUpdateOperation2();
    }

}
);

如果沒(méi)有返回值,使用TransactionCallbackWithoutResult, 如下:

tt.execute(new TransactionCallbackWithoutResult() {
    
protected void doInTransactionWithoutResult(TransactionStatus status) {
        updateOperation1();
        updateOperation2();
    }

}
);

回調中的代碼可以調用TransactionStatus的對象 setRollbackOnly()方法來(lái)回滾事務(wù)。

想要使用TransactionTemplate的應用程序類(lèi)必須訪(fǎng)問(wèn)一 個(gè)PlatformTransactionManager:通常通過(guò)一個(gè)javabean屬 性或構造函數參數暴露出來(lái)。

使用模擬或樁化的PlatformTransactionManager單元測試 這些類(lèi)很簡(jiǎn)單。沒(méi)有JNDI查找和靜態(tài)魔術(shù):它只是一個(gè)簡(jiǎn)單的接口。和平常一樣, 你可以使用Spring簡(jiǎn)化單元測試。

7.3.2. 使用PlatformTransactionManager

你也可以使用 org.springframework.transaction.PlatformTransactionManager 直接管理事務(wù)。簡(jiǎn)單地通過(guò)一個(gè)bean引用傳遞一個(gè)你使用的 PlatformTransactionManager實(shí)現到你的bean,然后, 使用TransactionDefinitionTransactionStatus對象就可以發(fā)起事務(wù),回滾和提交。

DefaultTransactionDefinition def = new DefaultTransactionDefinition()
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

TransactionStatus status 
= transactionManager.getTransactionDefinition(def);

try {
    
// execute your business logic here
}
 catch (MyException ex) {
    transactionManager.rollback(status);
    
throw ex;
}

transactionManager.commit(status);

7.4. 聲明式事務(wù)管理

Spring也提供了聲明式事務(wù)管理。這是通過(guò)Spring AOP實(shí)現的。

大多數Spring用戶(hù)選擇聲明式事務(wù)管理。這是最少的影響應用代碼的選擇, 因而這是和非入侵的輕量級容器的觀(guān)念是一致的。

從考慮EJB CMT和Spring聲明式事務(wù)管理的相似以及不同之處出發(fā)是很有益的。 基本方法是一致的:都可以指定事務(wù)管理到單獨的方法;如果需要可以在事務(wù)上 下文調用setRollbackOnly()方法。不同之處:

  • 不同于EJB CMT綁定在JTA上,Spring聲明式事務(wù)管理可以在任何環(huán)境下使用。 只需更改配置文件,它就可以和JDBC、JDO、Hibernate或其他的事務(wù)機制一起工作

  • Spring可以使聲明式事務(wù)管理應用到POJO,不僅僅是特定的類(lèi),如EJB

  • Spring提供聲明式回滾規則:EJB沒(méi)有對應的特性, 我們將在下面討論這個(gè)特性?;貪L可以聲明式控制,不僅僅是編程式的

  • Spring通過(guò)AOP提供定制事務(wù)行為的機會(huì )。例如,如果需要,你可以在事務(wù) 回滾中插入定制的行為。你也可以增加事務(wù)通知一樣增加任意的通知。使用 EJB CMT,除了使用setRollbackOnly()沒(méi)有其他的辦法能 夠影響容器的事務(wù)管理

  • Spring不提供高端應用服務(wù)器提供的跨越遠程調用的事務(wù)上下文傳播。如 果你需要這些特性,我們推薦你使用EJB。然而,不要過(guò)度使用這些特性。通常我 們并不希望事務(wù)跨越遠程調用

回滾規則的概念是很重要的:它們使得我們可以指定那些異常應該發(fā)起一個(gè)自 動(dòng)回滾。我們在配置文件中而不是Java代碼中指定這些聲明。因此,雖然我們仍 然可以編程式調用TransactionStatus對象的 setRollbackOnly()方法來(lái)回滾當前事務(wù),多數時(shí)候我們可以 指定規則如MyApplicationException應該用于導致一個(gè)回滾。 這有顯著(zhù)的優(yōu)點(diǎn),業(yè)務(wù)對象不需要依賴(lài)事務(wù)基礎設施。例如,他們通常不需要引 入任何Spring API,事務(wù)或其他任何東西。

EJB的默認行為是遇到系統異常(通常是運行時(shí)異常) EJB容器自動(dòng)回滾事務(wù)。EJB CMT遇到應用程序異常 (除了java.rmi.RemoteException外被檢查的異常)時(shí)不 會(huì )自動(dòng)回滾事務(wù)。雖然Spring聲明式事務(wù)管理沿用EJB CMT約定(遇到不被檢查的 異常自動(dòng)回滾事務(wù)),但是這是可以定制的。

按照我們的基準,Spring聲明式事務(wù)管理的性能要勝過(guò)EJB CMT。

通常設置Spring事務(wù)代理的方法是通過(guò)TransactionProxyFactoryBean。我們需 要一個(gè)包裝在事務(wù)代理中目標對象。這個(gè)目標對象一般是一個(gè)POJO的bean。當我 們定義TransactionProxyFactoryBean時(shí),必須提供一個(gè)相關(guān)的 PlatformTransactionManager的引用和事務(wù)屬性。 事務(wù)屬性含有上面描述的事務(wù)定義。

<bean id="petStore" 
    class
="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    
<property name="transactionManager"><ref bean="transactionManager"/></property>
    
<property name="target"><ref bean="petStoreTarget"/></property>
    
<property name="transactionAttributes">
        
<props>
            
<prop key="insert*">PROPAGATION_REQUIRED,-MyCheckedException</prop>
            
<prop key="update*">PROPAGATION_REQUIRED</prop>
            
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
        
</props>
    
</property>
</bean>

事務(wù)代理會(huì )實(shí)現目標對象的接口:這里是id為petStoreTarget.的bean(使用 CGLIB可以實(shí)現具體類(lèi)的代理,只要設置proxyTargetClass屬性為true就可以。這 將自動(dòng)設置,如果目標對象沒(méi)有實(shí)現任何接口。通常,我們希望面向接口而不是 類(lèi)編程)??梢裕ㄒ话銇?lái)說(shuō)是好的想法)限定事務(wù)代理使用proxyInterfaces來(lái)代 理指定的接口。也可以通過(guò)繼承至 org.springframework.aop.framework.ProxyConfig幾個(gè)屬 性來(lái)定制TransactionProxyFactoryBean的行為,并在所有的AOP代理工廠(chǎng)中共享。

這里的transactionAttributes通過(guò)定在 org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource 類(lèi)中的屬性格式來(lái)設置。這個(gè)包括通配符的方法名稱(chēng)映射是很直觀(guān)的。注意 insert*的映射的值包括回滾規則。添加-MyCheckedException 指定如果方法拋出MyCheckedException或它的子類(lèi),事務(wù)將 會(huì )自動(dòng)回滾??梢灾付▊€(gè)回滾規則,用逗號分隔。-前綴強制回滾,+前綴指定提 交(這允許即使拋出未被檢查的異常時(shí)也可以提交事務(wù),當然你自己要明白自己 在做什么)。

TransactionProxyFactoryBean允許你通過(guò) “preInterceptors”和“postInterceptors”屬性設置“前”或“后”通知來(lái)提供額外的 攔截行為??梢栽O置任意數量的“前”和“后”通知,它們的類(lèi)型可以是 Advisor(可以包含一個(gè)pointcut), MethodInterceptor或被當前Spring配置支持的通知類(lèi)型 (例如ThrowAdvice, AfterReturningtAdviceBeforeAdvice, 這些都是默認支持的)。這些通知必須支持實(shí)例共享模式。如果你需要高級AOP特 性來(lái)使用事務(wù),如有狀態(tài)的混入,那最好使用通用的 org.springframework.aop.framework.ProxyFactoryBean, 而不是TransactionProxyFactoryBean代理創(chuàng )建者。

也可以設置自動(dòng)代理:配置AOP框架,不需要單獨的代理定義類(lèi)就可以生成類(lèi)的 代理。

更多信息和實(shí)例請參閱AOP章節。

你不需要成為AOP專(zhuān)家,當然,了解更多的AOP知識,可以更有效地使用Spring 聲明式事務(wù)管理。但是,如果你想成為Spring AOP的高級用戶(hù),你會(huì )發(fā)現整合聲明 式事務(wù)管理和強大的AOP性能是非常容易的。

7.4.1. BeanNameAutoProxyCreator,另一種聲明方式

TransactionProxyFactoryBean非常有用,并且當事 務(wù)代理包裝對象時(shí),你有全部的支配權。如果你需要用一致的方式(例如,一個(gè) 樣板文件,“使所有的方法事務(wù)化”)包裝大量的bean,使用一個(gè) BeanFactoryPostProcessor調用 BeanNameAutoProxyCreator可以提供另外一種方法, 一個(gè)在這種簡(jiǎn)單的情況下更加簡(jiǎn)化的方法。

重述一下,一旦ApplicationContext讀完它的初始化信息,它將初始化所有實(shí) 現BeanPostProcessor的bean,并且給所有其他 ApplicationContext中beans一個(gè)后期處理的機會(huì )。所以使用這種機制,一個(gè)正 確配置的BeanNameAutoProxyCreator可以用來(lái)后期處 理所有ApplicationContext中所有其他的bean(通過(guò)名稱(chēng)來(lái)識別),并且把他 們用事務(wù)代理包裝起來(lái)。真正事務(wù)代理的生成和使用 TransactionProxyFactoryBean基本一致,這里不再 討論。

讓我們看下面的配置示例:

 

  <!-- Transaction Interceptor set up to do PROPOGATION_REQUIRED on all methods -->
  
<bean id="matchAllWithPropReq" 
      class
="org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource">
    
<property name="transactionAttribute"><value>PROPAGATION_REQUIRED</value></property>
  
</bean>
  
<bean id="matchAllTxInterceptor" 
      class
="org.springframework.transaction.interceptor.TransactionInterceptor">
    
<property name="transactionManager"><ref bean="transactionManager"/></property>
    
<property name="transactionAttributeSource"><ref bean="matchAllWithPropReq"/></property>
  
</bean>

  
<!-- One BeanNameAutoProxyCreator handles all beans where we want all methods to use 
       PROPOGATION_REQUIRED 
-->
  
<bean id="autoProxyCreator" 
      class
="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    
<property name="interceptorNames">
      
<list>
        
<idref local="matchAllTxInterceptor"/>
        
<idref bean="hibInterceptor"/>
      
</list>
    
</property>
    
<property name="beanNames">
      
<list>
        
<idref local="core-services-applicationControllerSevice"/>
        
<idref local="core-services-deviceService"/>
        
<idref local="core-services-authenticationService"/>
        
<idref local="core-services-packagingMessageHandler"/>
        
<idref local="core-services-sendEmail"/>
        
<idref local="core-services-userService"/>
      
</list>
    
</property>
  
</bean>

假設我們已經(jīng)有一個(gè)TransactionManager的實(shí)例 在A(yíng)pplicationContext中,我們首先要做的使創(chuàng )建一個(gè) TransactionInterceptor實(shí)例。 ransactionInterceptor基于一個(gè)實(shí)現 TransactionAttributeSource接口的對象決定哪個(gè) 方法被攔截, 這個(gè)對象作為屬性傳遞進(jìn)來(lái)的。這個(gè)例子中,我們希望處理匹配 所有方法這種最簡(jiǎn)單的情況。這個(gè)不是最有效的方式,但設置非常迅速,因為 我可以使用預先定義的匹配所有方法的 MatchAlwaysTransactionAttributeSource類(lèi)。如果我 們需要特定的方式,可以使用 MethodMapTransactionAttributeSource, NameMatchTransactionAttributeSourceAttributesTransactionAttributeSource。

現在我們已經(jīng)有了事務(wù)攔截器,我們只需把它和另外6個(gè)我們希望以一致方式 包裝的AppliactonContext中的bean一起放到我們定義的 BeanNameAutoProxyCreator實(shí)例中。你可以看到,這 個(gè)結果比用TransactionProxyFactoryBean以一種方式單獨包裝6個(gè)bean簡(jiǎn)捷很 多。包裝第7個(gè)bean只需添加一行配置。

你也許注意到可以應用多個(gè)攔截器。在這個(gè)例子中,我們也可以應用一個(gè)預 先定義的HibernateInterceptor (bean id=hibInterceptor),這個(gè)為我們管理 Hibernare的Sessions。

有一件事值得注意,就是在TransactionProxyFactoryBean, 和BeanNameAutoProxyCreator切換時(shí)bean的名稱(chēng)。 第一種情況,你只需給你想要包裝的bean一個(gè)類(lèi)似 myServiceTarget的id, 給代理對象一個(gè)類(lèi)似myService的id, 然后所有代理對象的用戶(hù)只需引用代理對象, 如myService(這些是通用命名規范, 要點(diǎn)是目標對象要有和代理對象不同的名稱(chēng), 并且他們都要在A(yíng)pplicationContext中可用)。然而, 使用BeanNameAutoProxyCreator時(shí), 你命名目標對象為myService。 然后當BeanNameAutoProxyCreator后期處理目標對象 并生成代理時(shí),它導致代理以和原始對象相同的名稱(chēng)被插入到 ApplicationContext中。從這一點(diǎn)看,只有代理(含有被包裝的對象)在A(yíng)pplication中可用。

7.5. 編程式還是聲明式事務(wù)管理

如果你只有很少的事務(wù)操作,使用編程式事務(wù)管理是很好的主意。例如, 如果你有一個(gè)WEB應用需要為某些更新操作提供事務(wù),你可能不想用Spring或其 他技術(shù)設置一個(gè)事務(wù)代理。使用 TransactionTemplate可能是個(gè)很好的方法。

另一方面,如果你的應用有大量的事務(wù)操作,編程式(譯注:應為聲明式, 疑是作者筆誤)事務(wù)管理通常是很有價(jià)值的。它使得事務(wù)管理從業(yè)務(wù)邏輯分離, 并且Spring中配置也不困難。使用Spring, 而不是EJB CMT,聲明式事務(wù)管理配置的成本極大地降低。

7.6. 你需要應用服務(wù)器管理事務(wù)嗎?

Spring的事務(wù)管理能力――尤其聲明式事務(wù)管理極大地改變了J2EE應用程序需要 應用服務(wù)器的傳統想法。

特別地,你不需要應用服務(wù)器僅僅為了通過(guò)EJB聲明事務(wù)。事實(shí)上,即使你擁 有強大JTA支持的應用服務(wù)器,你也可以決定使用Spring聲明式事務(wù)管理提供比 EJB CMT更強大更高效的編程模型。

只有需要支持多個(gè)事務(wù)資源時(shí)你才需要應用服務(wù)器的JTA支持。許多應用沒(méi)有 這個(gè)需求。例如許多高端應用使用單一的高度可升級的數據庫,如Oracle 9i RAC。

當然也許你需要其他應用服務(wù)器的功能,如JMS和JCA。但是如果你只需使用 JTA,你可以考慮開(kāi)源的JTA實(shí)現,如JOTM(Spring整合了JOTM)。但是, 2004年早期,高端的應用服務(wù)器提供更健壯的XA資源支持。

最重要一點(diǎn),使用Spring,你可以選擇何時(shí)將你的應用遷移到完整 應用服務(wù)器。除了使用EJB CMT和JTA只能書(shū)寫(xiě)代碼使用局部事務(wù), 例如JDBC連接的事務(wù),而且如果曾經(jīng)需要全局的容器管理的事務(wù),還面臨著(zhù)繁重 的改寫(xiě)過(guò)程,這些日子一去不復返了。使用Spring只有配置需要改變,你的代碼 不需要。

7.7. 公共問(wèn)題

開(kāi)發(fā)著(zhù)需要按照需求仔細的使用正確的 PlatformTransactionManager實(shí)現。

理解Spring事務(wù)抽象時(shí)如何和JTA全局事務(wù)一起工作是非常重要的。使用得當, 沒(méi)有任何沖突:Spring僅僅提供一個(gè)簡(jiǎn)單的,可以移植的抽象層。

如果你使用全局事務(wù),你必須為你的所有事務(wù)操作使用Spring的 org.springframework.transaction.jta.JtaTransactionManager。 否則Spring將試圖在資源如容器數據源執行局部事務(wù)。這樣的局部事務(wù)沒(méi)有任何 意義,好的應用服務(wù)器會(huì )把這作為一個(gè)錯誤。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
為什么需要Spring
JTA
Spring聲明式事務(wù)策略-Spring-Java -JavaEye做最棒的軟件開(kāi)發(fā)交流社區
Java事務(wù)處理總結
pojo應用框架:spring vs. ejb 3.0(翻譯文章,原創(chuàng ))
基于Spring框架的WebSphere應用開(kāi)發(fā)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久