走自己的路

          路漫漫其修遠兮,吾將上下而求索

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            50 隨筆 :: 4 文章 :: 118 評論 :: 0 Trackbacks

          晚上要下班的時候,application team那里使用Tibco EMS做消息集成服務時候出了bug,錯誤是:java.sql.SQLException: 當全局事務處理處于活動狀態時, 無法調用方法 'commit',應該是在全局事務中使用了本地事務并提交了。幫忙看了一下,它的oc4j, toplink, spring的使用上都存在著一些問題,并把要注意的地方總結了一下。
           

           Jta外部事務,也稱為分布式事務,全局事務。

           

          1. oc4j:

          ·         transaction manager知道resource的存在

           

          要使用外部事務,首先要讓transaction manager了解是哪個resource。我們選擇使用managed resource,這樣由容器來管理:data source, jms resouce, jca resourceoc4jtransaction manager肯定是知道這些managed resource的存在的,可以通過radata-sources.xml來配置,或者直接通過oc4j web console來創建。

                     

          • Oc4j data-sources.xml

           特別要注意的是data source的設置,oc4j中可以通過data-sources.xml設置transaction level,默認是global,表示join jta外部事務,如果是localoc4j就會把所有的managed datasource的操作當作local connection來看待,這些操作是不join到外部事務中的。

          什么是一次local transaction操作呢?

          Toplink:每次對unitofwork的提交。

          Connection的每次提交,auto commit的每次操作。

           

               <managed-data-source name="MIFSystemLogDataSource"

                    connection-pool-name="MIFSysLogConnectionFactory"

                    jndi-name="jdbc/mifStatusLog"  tx-level='global'/>

           

           有人會問沒有使用xaconnection怎么能使用外部事務join transaction呢,oracle實現了稱為Emulating XAoc4j container),它基本上模擬了two phase commit的功能,但是沒有transaction branches,也就是xidbranch標識符,xid包括format標識符, global事務標識符和branch標識符。也沒有two phase commit的預提交過程。Toplink在使用session broker時,也有類似的配置,稱為two stage commitxaresource應該配置成globaltransaction,否則沒必要用xa

           

          • Oc4j中如何自己控制transaction

          有時我們可能需要自己控制transaction,這樣我們可能需要在oc4j中獲得受管的UserTransactionTransactionManagerTransactionManager可以suspendresume一個transaction,實現諸如requires new這樣的功能。

                Context initialContext = new InitialContext();

                UserTransaction userTrx = (javax.transaction.UserTransaction) initialContext.lookup("java:comp/UserTransaction");

                      if (ut instanceof TransactionManager) {

                                  TransactionManager tm = (TransactionManager) userTrx;

           

          }

           

          • 如果使用的是分布式全局transaction不建議在程序中調用connection.setAutoCommit(true), connection.commit(), commit.rollback()方法,這樣會干擾分布式事務的管理。

          2Toplink

           

          • 如果toplink需要跨多個data source,請使用session broker

          <session>

          <name>EmployeeSession</name>

          ...

          </session>

          <session>

          <name>ProjectSession</name>

          ...

          </session>

          /* Configure the SessionBroker */

          <session-broker>

          /* Name the SessionBroker */

          <name>EmployeeAndProjectBroker</name>

          /* Specify the sessions contained in the SessionBroker */

          <session-name>EmployeeSession</session-name>

          <session-name>ProjectSession</session-name>

          </session-broker>

           

          • 如果toplink的操作想join到外部事務,或者說使用two phase commit,需要在session中激活使用是用外部事務,可以通過sessions.xml配置:

          <external-transaction-controller>true</external-transaction-controller>

           

           

          3Spring

           

          • 使用外部事務

                <bean name="transactionManager"

                      class="org.springframework.transaction.jta.OC4JJtaTransactionManager" >

                </bean>

           

          或者

                <bean name="transactionManager"

                      class="org.springframework.transaction.jta.JtaTransactionManager" >

                </bean>

           

          • 本地事務

                <bean name="transactionManager"

                      class=" org.springframework.orm.toplink. TopLinkTransactionManager " >

                    <property name="sessionFactory" ref="sessionFactory" />

                </bean>




          評論

          # re: oc4j+toplink+spring使用jta外部事務的一點心得 2008-11-15 11:14 life126.com
          總感覺這樣做會很不穩定,現在數據庫供應商的多數據源事務也沒有很好的解決辦法  回復  更多評論
            

          # re: oc4j+toplink+spring使用jta外部事務的一點心得[未登錄] 2008-11-18 22:20 vv
          怎么用這么怪的技術,比hibernate等成熟的開源技術有什么優勢?  回復  更多評論
            

          # re: oc4j+toplink+spring使用jta外部事務的一點心得 2008-11-19 11:15 ldd600
          @vv
          您的意思是說toplink用起來很怪?我說一下我的看法:
          1.toplink是開源的但并不完全,toplink internal沒有開源
          2.eclipselink是完全開源的,是toplink的升級版本,貌似將作為jpa2.0的參考實現
          3.toplink有很強大可視化的orm工具而且它的mapping功能也是很強大的
          4.它oracle數據庫 oracle ias整合還是很完美的,畢竟是oracle的產品
          5.其實不能說toplink就怎么怎么不好,各有各的長處吧。可能toplink沒有hibernate用的那么普遍。  回復  更多評論
            

          # re: oc4j+toplink+spring使用jta外部事務的一點心得 2008-11-19 11:40 ldd600
          @life126.com
          現在很多企業級應用應該都使用了分布式事務吧,而且數據庫廠商競爭那么激烈,分布式事務(xa接口)應該都實現了,成熟不成熟也見仁見智了吧。  回復  更多評論
            

          # re: oc4j+toplink+spring使用jta外部事務的一點心得 2009-07-12 00:53 yanical
          大致按你說的做了,出了個問題:
          Exception Description: Sequencing login should not use External Transaction Controller.
          網上查了一下,我覺得是datasource配置錯了,該怎么配?  回復  更多評論
            

          # re: oc4j+toplink+spring使用jta外部事務的一點心得 2009-07-12 09:30 ldd600
          不知道您是否顯式的配置了sequence用的connection pool,sequence(identity id)的申請是不能用jta的,請不要顯式的設置它,保持默認就可以了。不知道您是否方便把您的sessions.xml發給我,我們一起看一下。  回復  更多評論
            

          # re: oc4j+toplink+spring使用jta外部事務的一點心得 2009-07-12 11:51 yanical

          <login xsi:type="database-login">
          <platform-class>oracle.toplink.platform.database.oracle.Oracle10Platform</platform-class>
          <external-connection-pooling>true</external-connection-pooling>
          <external-transaction-controller>false</external-transaction-controller>
          <sequencing>
          <default-sequence xsi:type="table-sequence">
          <name>Custom</name>
          <preallocation-size>50</preallocation-size>
          <table>SEQUENCE</table>
          </default-sequence>
          </sequencing>
          <datasource>%%DS_LOCATION%%</datasource>
          <bind-all-parameters>true</bind-all-parameters>
          <batch-writing>true</batch-writing>
          </login>
          <connection-pools>
          <sequence-connection-pool>
          <name>SequenceConnectionPool</name>
          <max-connections>10</max-connections>
          <min-connections>2</min-connections>
          <login xsi:type="database-login">
          <external-connection-pooling>true</external-connection-pooling>
          <external-transaction-controller>true</external-transaction-controller>
          <sequencing>
          <default-sequence xsi:type="table-sequence">
          <name>Custom</name>
          <table>SEQUENCE</table>
          </default-sequence>
          </sequencing>
          <datasource>%%DS_LOCATION%%</datasource>
          </login>
          </sequence-connection-pool>
          </connection-pools>
          這是主要部分,之前把兩個external-transaction-controller都設成true,
          拋Exception Description: Sequencing login should not use External Transaction Controller.
          現在上面那個設成false,可以啟動系統,但是程序中調用assignSequenceNumber時就拋異常:有外部transaction,不能commit.
          謝謝幫看一下  回復  更多評論
            

          # re: oc4j+toplink+spring使用jta外部事務的一點心得 2009-07-12 11:58 yanical
          不好意思,好像一調用數據庫操作就會
          The method 'commit' cant be called
          when a global transaction is active.  回復  更多評論
            

          # re: oc4j+toplink+spring使用jta外部事務的一點心得 2009-07-12 17:00 ldd600
          我覺得上面應該設成true,下面設成false,您可以試一下。  回復  更多評論
            

          # re: oc4j+toplink+spring使用jta外部事務的一點心得 2009-07-12 17:48 yanical
          不行啊,Exception Description: Sequencing login should not use External Transaction Controller.  回復  更多評論
            

          # re: oc4j+toplink+spring使用jta外部事務的一點心得 2009-07-12 19:57 ldd600
          可以不用為sequence設置pool,它可以自動重用先前你配置的xa pool的,只是會增加沖突率,可以適當的增加預取的oid數,我們公司的應用項目組應該是這么配置的。

          不好意思,顯著的把它設成false也是錯誤的,我一開始以為它會suspend掉jta transaction。如果考慮到其他問題你可以單獨為它設一個local的datasource吧。

          <managed-data-source name="myLocalDS"
          connection-pool-name="myPool"
          jndi-name="jdbc/myLocalDS"
          tx-level="local"/>

            回復  更多評論
            

          主站蜘蛛池模板: 镇平县| 芜湖县| 岳普湖县| 卓尼县| 莲花县| 石首市| 蛟河市| 卢龙县| 常熟市| 澄江县| 龙州县| 通化市| 石楼县| 英德市| 芒康县| 澄迈县| 黔江区| 阳信县| 鄂温| 万年县| 南岸区| 北安市| 西林县| 卓尼县| 巍山| 阳城县| 左权县| 布拖县| 大方县| 汝城县| 资中县| 田东县| 南充市| 临沂市| 建德市| 长阳| 江川县| 天长市| 历史| 新丰县| 乾安县|