汇聚你我之力......

oc4j+toplink+spring使用jta外部事务的一点心得

上一篇 / 下一篇  2008-11-17 08:18:30 / 个人分类:Spring

晚上要下班的时候,application team那里使用Tibco EMS做消息集成服务时候出了bug,错误是:java.sql.SQLException: 当全局事务处理处于活动状态时, 无法调用方法 'commit',应该是在全局事务中使用了本地事务并提交了。帮忙看了一下,它的oc4j, toplink, spring的使用上都存在着一些问题,并把要注意的地方总结了一下。 

 Jta外部事务,也称为分布式事务,全局事务。 

oc4j:
·         让transaction manager知道resource的存在 

要使用外部事务,首先要让transaction manager了解是哪个resource。我们选择使用managed resource,这样由容器来管理:data source, jms resouce, jca resource,oc4j的transaction manager肯定是知道这些managed resource的存在的,可以通过ra,data-sources.xml来配置,或者直接通过oc4j web console来创建。           

Oc4j data-sources.xml
 特别要注意的是data source的设置,oc4j中可以通过data-sources.xml设置transaction level,默认是global,表示join jta外部事务,如果是local,oc4j就会把所有的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'/>
 

 有人会问没有使用xa的connection怎么能使用外部事务join transaction呢,oracle实现了称为Emulating XA(oc4j container),它基本上模拟了two phase commit的功能,但是没有transaction branches,也就是xid的branch标识符,xid包括format标识符, global事务标识符和branch标识符。也没有two phase commit的预提交过程。Toplink在使用session broker时,也有类似的配置,称为two stage commit。xa的resource应该配置成global的transaction,否则没必要用xa。 

Oc4j中如何自己控制transaction
有时我们可能需要自己控制transaction,这样我们可能需要在oc4j中获得受管的UserTransaction和TransactionManager,TransactionManager可以suspend和resume一个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()方法,这样会干扰分布式事务的管理。
2.Toplink

如果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> 

3.Spring

使用外部事务
      <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>


TAG: java spring

引用 删除 Guest   /   2009-06-16 16:46:52
 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2009-07-05  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 34515
  • 日志数: 392
  • 文件数: 1
  • 书签数: 1
  • 建立时间: 2008-07-07
  • 更新时间: 2009-01-15

RSS订阅

Open Toolbar