隨筆-3  評論-2  文章-1  trackbacks-0

                最近偶參與一個(gè)J2EE項(xiàng)目,應(yīng)用架框是struts+spring! 持久層用hibernate,由于業(yè)務(wù)需要,業(yè)務(wù)數(shù)據(jù)來源來二個(gè)不同的數(shù)據(jù)庫數(shù)據(jù)庫是Orcale,版本是9.0.1.0.0。由于采用容器管理事務(wù)(CMT),對于Spring,一般普通業(yè)務(wù)應(yīng)用我用聲明式事務(wù),因?yàn)檫@樣讓代碼清潔一點(diǎn),只有對于特殊的業(yè)務(wù)我才用編程式事務(wù),如大批量更新時(shí)調(diào)用存儲過程。對于WebLogic Server,JTA TransactionManager的正式JNDI位置是javax.transaction.TransactionManager。在Spring 的JtaTransactionManager中,該值可被指定為“transactionManagerName”。這啟用了使用WebLogic JTA子系統(tǒng)的Spring驅(qū)動的事務(wù)掛起激活了對PROPAGATION_REQUIRES_NEW和PROPAGATION_NOT_SUPPORTED的支持。對于聲明式事務(wù)我配置在spring的service層,對于編程式事務(wù)則在持久層。
          下面說一下我的系統(tǒng)分層:acton==>service==>serviceImpl===>DAO===>DAOImpl,由業(yè)務(wù)層的實(shí)現(xiàn)類調(diào)用持久層的DAO接口,為了避免DAO的過度設(shè)計(jì)而使重用性降低,我這里每一個(gè)DAO接口對應(yīng)操作數(shù)據(jù)庫表,由spring的IOC容器注入,這樣在serviceImpl層中可以最大程序的重用DAO。因?yàn)橛捎跇I(yè)務(wù)需要一個(gè)serviceImpl需要從兩個(gè)數(shù)據(jù)庫中交換數(shù)據(jù)。操作DAO可以保證處于同一個(gè)事務(wù)中......

          事務(wù)的屬性和基本概念
            Required:
          如果在一個(gè)事務(wù)中調(diào)用,就把該方法加到此事務(wù)中來,如果還沒有啟動事務(wù),就啟動一個(gè)新事務(wù)。
            RequiredNew:
          不管當(dāng)前有沒有事務(wù),都會啟動一個(gè)新事務(wù),如果當(dāng)前有事務(wù),會被掛起直到方法結(jié)束。
            NotSupported:
          不能在事務(wù)中執(zhí)行此方法。如果有事務(wù),將會被掛起直到方法結(jié)束。
            Supports:
          如果當(dāng)前有事務(wù),此方法會加到當(dāng)前事務(wù),如果沒有,容器也不會啟動新事務(wù)。
            Mandatory:
          必須在事務(wù)中調(diào)用此方法,否則拋出異常:TransactionRequiredException。
            Never:
          必須不在事務(wù)中調(diào)用此方法,否則拋出RemoteException(遠(yuǎn)程調(diào)用)或EJBException(本地調(diào)用)

          以下FAQ來自http://dev2dev.bea.com.cn
          Q:XA 的Driver 和普通的Driver 有什么區(qū)別呢?

          A: XA 的Driver 支持分布式的事務(wù)處理,這是與non xa driver 的最大區(qū)別;JDBC2.0 規(guī)范提供了進(jìn)行分布式事務(wù)的能力。分布式事務(wù)是個(gè)單獨(dú)的事務(wù),可以應(yīng)用在位于分離服務(wù)器上的多個(gè)異構(gòu)數(shù)據(jù)庫。為了支持分布式事務(wù), JDBC2.0 提供了兩個(gè)新的接口:javax.sql.XADataSource 和javax.sql.XAConnection。從性能的考慮來說,使用XA 的DRIVER
          會比普通的DRIVER 慢。

          Q: XA 的連接池,選擇了支持本地事務(wù)后,是否還支持對全局的操作?

          A: 8.1 既支持TX,也支持Non-Tx 的,Weblogic 對所有的已知數(shù)據(jù)庫進(jìn)行了包裝(Wrapper),使接口一致,然而對不同的數(shù)據(jù)庫,根據(jù)選擇的驅(qū)動程序不同,都作了相應(yīng)的優(yōu)化和處理。建立數(shù)據(jù)源時(shí),如果選擇Non-Tx 類型,那么它參與到JTA 事務(wù)中也不會出錯(cuò),因?yàn)閃eblogic 會啟動本地事務(wù),但是前提是必須有一個(gè)資源(XAResource)參與到事務(wù)中(多個(gè)資源的話必須打開模擬兩
          階段提交協(xié)議,不然會出錯(cuò)),但是選擇Tx 類型的就必須有一個(gè)全局事務(wù),除非選擇支持本地事務(wù)(SupportsLocalTransaction=true)。另外如果使用了本地事務(wù),就必須設(shè)置autocommit 為true,或者手工commit/rollback。

          Q: 資料上講distributed transaction 只能用JTA 的XAResource 來控制事務(wù),如JMS 要參加分布式事務(wù)的話就必須用XA 的。但是,我記得在我們的應(yīng)用中如果在一個(gè)容器管理的事務(wù)中修改兩個(gè)不同的數(shù)據(jù)庫(這兩個(gè)庫在一臺機(jī)器的同一個(gè)實(shí)例中),那么必須用XA 的driver,難道這也是一種distribued transaction 嗎?(它們是同一種資源,都是JDBC,只是跨庫而已,為什么屬于分布式事務(wù)呢?)

          A: 分布式事務(wù)分事務(wù)管理器,資源管理器,應(yīng)用程序,以及底層事務(wù)通訊管理.在xa 中一個(gè)db就是一個(gè)資源.一個(gè)jms 也可以看作是一個(gè)資源,事務(wù)管理器就是協(xié)調(diào)這些資源進(jìn)行統(tǒng)一commit 或者rollback 的,所以來說跨庫就屬于分布式事務(wù)了。


          具體操作步驟:

          1、Configure a new JDBC Connection Pool:先在weblogic console中配置連接池,這里用
            Oracle's Deriver(Thin XA) Versions:8.1.7.9.0.1.9.2.0, 并把Supports Local Transaction勾上。
            
          2、Configure a new JDBC Data Source:配置一個(gè)數(shù)據(jù)源,并綁定上面創(chuàng)建的連接池。

          3、在spring的ApplicationContext.xml中配置:
            
             

            1Jndi:
            2    <bean id="myDataSource1" class="org.springframework.jndi.JndiObjectFactoryBean">
            3            <property name="jndiName">
            4                <value>ds1</value>
            5            </property>
            6        </bean>
            7        
            8        <bean id="myDataSource2" class="org.springframework.jndi.JndiObjectFactoryBean">
            9            <property name="jndiName">
           10                <value>ds2</value>
           11            </property>
           12        </bean>
           13        
           14     Jta:
           15     <bean id="myTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
           16     
           17     SessionFactory:
           18     <bean id="mySessionFactory1" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
           19            <property name="mappingResources">
           20                <list>
           21                    <value>myOne.hbm.xml</value>
           22                    <value>myTwo.hbm.xml</value>        
           23                </list>
           24            </property>
           25            <property name="hibernateProperties">
           26                <props>
           27                    <prop key="hibernate.dialect">net.sf.hibernate.dialect.OracleDialect</prop>
           28                    <prop key="hibernate.show_sql">true</prop>
           29          <prop key="hibernate.jdbc.fetch_size">50</prop>
           30          <prop key="hibernate.jdbc.batch_size">0</prop>
           31                </props>
           32            </property>
           33            <property name="dataSource">
           34                <ref bean="myDataSource1"/>
           35            </property>
           36        </bean>
           37        
           38        <bean id="mySessionFactory2" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
           39            <property name="mappingResources">
           40                <list>
           41                    <value>youOne.hbm.xml</value>
           42                    <value>youTwo.hbm.xml</value>        
           43                </list>
           44            </property>
           45            <property name="hibernateProperties">
           46                <props>
           47                    <prop key="hibernate.dialect">net.sf.hibernate.dialect.OracleDialect</prop>
           48                    <prop key="hibernate.show_sql">true</prop>
           49          <prop key="hibernate.jdbc.fetch_size">50</prop>
           50          <prop key="hibernate.jdbc.batch_size">0</prop>
           51                </props>
           52            </property>
           53            <property name="dataSource">
           54                <ref bean="myDataSource2"/>
           55            </property>
           56        </bean>
           57
           58   TranscationManager
           59    <bean id="TransactionProxyFactoryBean" abstract="true" lazy-init="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
           60            <property name="transactionManager" ><ref bean="myTransactionManager" /></property> 
           61            <property name="transactionAttributes" > 
           62            <props> 
           63                <prop key="find*" >PROPAGATION_REQUIRED,readonly</prop>
           64                <prop key="save*" >PROPAGATION_REQUIRED</prop>
           65                <prop key="update*" >PROPAGATION_REQUIRED</prop> 
           66                <prop key="delete*" >PROPAGATION_REQUIRED</prop>
           67                <prop key="do*" >PROPAGATION_REQUIRED</prop>   
           68            </props> 
           69            </property> 
           70    </bean>
           71    
           72    DAO配置
           73    <bean id="serviceImpl" parent="TransactionProxyFactoryBean">        
           74                <property name="target">
           75                   <bean class="com.hi.services.spring.business.SomeServiceImpl">
           76                        <property name="dao1"><ref local="dao1"/></property>
           77                        <property name="dao2"><ref local="dao2"/></property>
           78                        <property name="dao3"><ref local="dao3"/></property>
           79                   </bean>
           80                </property>    
           81  </bean> 
           82    
           834 修改weblogic服務(wù)器你發(fā)布的domains文件下的config.xml,加上RollbackLocalTxUponConnClose="true",如果這句話不加上
           84insert*、delete*、upate*無法提交。
           85  <JDBCConnectionPool
           86        DriverName="oracle.jdbc.xa.client.OracleXADataSource"
           87        Name="baseXaPool" Password="{3DES}RBDwPC7KmTq1MGymoUMieg=="
           88        Properties="user=admin" RollbackLocalTxUponConnClose="true"
           89        SupportsLocalTransaction="true" Targets="myserver"
           90        TestConnectionsOnCreate="false" TestConnectionsOnRelease="false"
           91        TestConnectionsOnReserve="false"
           92        TestTableName="SQL SELECT 1 FROM DUAL" URL="jdbc:oracle:thin:@192.168.0.7:1521:flyjie"/>
           93  <JDBCConnectionPool
           94        DriverName="oracle.jdbc.xa.client.OracleXADataSource"
           95        Name="applicationXaPool" Password="{3DES}RBDwPC7KmTq1MGymoUMieg=="
           96        Properties="user=flyjie" RollbackLocalTxUponConnClose="true"
           97        SupportsLocalTransaction="true" Targets="myserver"
           98        TestConnectionsOnCreate="false" TestConnectionsOnRelease="false"
           99        TestConnectionsOnReserve="false"
          100        TestTableName="SQL SELECT 1 FROM DUAL" URL="jdbc:oracle:thin:@192.168.0.55:1521:application"/>
          101
          102一個(gè)例子:
          103       public class SomeServiceImpl implements ISomeService{
          104               
          105               private IDao1 dao1; //操作mySessionFactory1的表
          106               private IDao2 dao2; //操作mySessionFactory2的表
          107               private IDao3 dao3; //操作mySessionFactory1的表
          108               //.get
          109               
          110               ///set
          111               public Object doIn(Object[] object){
          112                  String sql = (String)object[1];
          113                  List resultList = (ArrayList)getIDao1().findPeronList(sql);
          114                  //..某些業(yè)務(wù)操作
          115                  for(.)
          116                  getIDao2().save(resultList.get(i));
          117                  //
          118                  update(object);
          119               }

          120               
          121               public void update(Object object){
          122                 getIDao3().update(//);
          123               }

          124          }

                   
          注意的問題:由于配置不當(dāng)引起的serive層中的事務(wù)嵌套,這一個(gè)人很惱人的問題。我們在配置聲明式事務(wù)時(shí)一般是以service層中的方法名來作來啟動事務(wù)的標(biāo)志。如save*,find*,你的serviceImpl中有save方法或findList方法,
          spring會在自動把在該方法內(nèi)操作的資源納入到同一個(gè)事務(wù)中,以保證數(shù)據(jù)ACID(Atomicity、Consistency、Isolation、Durability)。

          關(guān)于Spring的事務(wù)請參考Spring Framework 開發(fā)參考手冊
          http://www.jactiongroup.net/reference/html/index.html

          posted on 2005-11-23 11:16 java驛館 閱讀(93) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 竹溪县| 横山县| 南开区| 邛崃市| 南丹县| 璧山县| 乐亭县| 灵璧县| 内江市| 深水埗区| 武穴市| 布拖县| 贞丰县| 额济纳旗| 明光市| 安福县| 安图县| 嘉善县| 开原市| 清流县| 长春市| 屏南县| 丰原市| 海晏县| 遂平县| 河北省| 千阳县| 胶州市| 清涧县| 五台县| 丽水市| 崇左市| 玛纳斯县| 曲水县| 遵化市| 华安县| 庐江县| 含山县| 长海县| 怀远县| 新巴尔虎右旗|