今天为了这个问题了忙乎了一整天,特此记录下,希望对有遇到同样问题的同学有帮助。事情的经过是这样的,原先使用atomikos一直把数据源用jndi配置到tomcat的context.xml下,一直这么用没有出现问题,配置如下
<Resource name="jdbc/cms" auth="Container"
type="com.atomikos.jdbc.AtomikosDataSourceBean" factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory"
uniqueResourceName="jdbc/cms" xaDataSourceClassName="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"
xaProperties.URL="xxxx"
xaProperties.user="xxxx" xaProperties.password="xxxx"
xaProperties.pinGlobalTxToPhysicalConnection="true" maxLifetime="60" poolSize="4" />
最近项目要迁移到maven下,所以把context.xml的数据源配置挪到了spring.xml下,配置如下
<bean id="myDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="masterDB" />
<property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/> <!-- SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana] -->
<property name="poolSize" value="0" />
<property name="minPoolSize" value="0"/>
<property name="maxPoolSize" value="9"/>
<property name="borrowConnectionTimeout" value="60"/>
<property name="reapTimeout" value="20"/>
<property name="maxIdleTime" value="60"/>
<property name="maintenanceInterval" value="60"/>
<property name="loginTimeout" value="60"/>
<property name="xaProperties">
<props>
<prop key="url">xxxx</prop>
<prop key="user">xxxx</prop>
<prop key="password">xxxx</prop>
</props>
</property>
</bean>
因为上面这个配置我是照搬网上的,所以觉得没有问题,可是项目启动后,用此数据源提交事务时确报以下错误:
Raised -5: invalid arguments were given for the XA operation 或 XAER_INVAL: Invalid arguments (or unsupported command)
一开始我以为maven配置的mysql-connector-java驱动版本不对,或是atomikos版本不对,可是不管如何换版本都不行,就快要疯了的时候,我看到了原先jndi方式中有这么一行代码
xaProperties.pinGlobalTxToPhysicalConnection="true"
就因为缺少上面这句话导致了问题,上网查资料,据说是mysql xa bug,有兴趣的可以看如下连接,最后配置如下:
<property name="xaProperties">
<props>
<prop key="pinGlobalTxToPhysicalConnection">true</prop> <!-- mysql必须配置此参数,要不然无法提交事务 -->
<prop key="url">xxxx</prop>
<prop key="user">xxx</prop>
<prop key="password">xxxx</prop>
</props>
</property>