走自己的路

路漫漫其修远兮,吾将上下而求索

  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"/>

  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: