1

我有一个春季批处理项目,并且正在使用 Atomikos 进行事务管理。

这是我的数据源配置和 atomikos 配置。

  @Bean
  public DataSource dataSource() {
    Properties properties = new Properties();
    properties.setProperty("serverName", "localhost");
    properties.setProperty("databaseName", "somedb");
    properties.setProperty("portNumber", "9999");
    properties.setProperty("currentSchema", "sch");    
    properties.setProperty("user", "user");
    properties.setProperty("password", "pwd");
    properties.setProperty("driverType", "4");
    properties.setProperty("resultSetHoldability","2");


    AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
    atomikosDataSourceBean.setXaDataSourceClassName("com.ibm.db2.jcc.DB2XADataSource");
    atomikosDataSourceBean.setXaProperties(properties);
    atomikosDataSourceBean.setPoolSize(5);
    return atomikosDataSourceBean;
}


 @Bean(initMethod = "init", destroyMethod = "close")
public UserTransactionManager atomikosTransactionManager(){
    UserTransactionManager atomikosTransactionManager = new UserTransactionManager();
    atomikosTransactionManager.setForceShutdown(false);
    return atomikosTransactionManager;

}

@Bean 
public UserTransactionImp atomikosUserTransaction() throws SystemException{
    UserTransactionImp atomikosUserTransaction = new UserTransactionImp();
    atomikosUserTransaction.setTransactionTimeout(300);
    return atomikosUserTransaction;
}

@Bean
public JtaTransactionManager transactionManager(UserTransactionManager atomikosTransactionManager, UserTransactionImp atomikosUserTransaction) throws SystemException{
    JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
    jtaTransactionManager.setTransactionManager(atomikosTransactionManager);
    jtaTransactionManager.setUserTransaction(atomikosUserTransaction);
    jtaTransactionManager.setAllowCustomIsolationLevels(true);
    return jtaTransactionManager;
}

 @Bean
public LocalContainerEntityManagerFactoryBean  entityManagerFactory(DataSource dataSource) {
    final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource);
    em.setJtaDataSource(dataSource);
    em.setPackagesToScan("org.company.entity");
    em.setJpaVendorAdapter(new OpenJpaVendorAdapter());
    em.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
    em.setSharedCacheMode(SharedCacheMode.ALL);
    em.setJpaProperties(additionalProperties());

    return em;
}

final Properties additionalProperties() {
    final Properties openJpaProperties = new Properties();
    openJpaProperties.setProperty("javax.persistence.transactionType","jta");       
    openJpaProperties.setProperty("openjpa.TransactionMode", "local");
    openJpaProperties.setProperty("openjpa.ConnectionFactoryMode", "local");
    openJpaProperties.setProperty("openjpa.MetaDataRepository", "Preload=true");
    openJpaProperties.setProperty("openjpa.Compatibility", "QuotedNumbersInQueries=true");
    openJpaProperties .setProperty("openjpa.ConnectionFactoryProperties", "PrettyPrint=true, PrettyPrintLineLength=80, PrintParameters=true");
    return openJpaProperties;
}

当我调用 spring 存储库来更新数据库时,它会抛出一个错误,提示 Invalid operation: setAutoCommit(true) is not allowed during Global Transaction。请参阅下面的堆栈跟踪。对此的任何想法都会非常有帮助。

com.ibm.db2.jcc.am.SqlException: [jcc][t4][10126][10304][3.62.56] Invalid     operation: setAutoCommit(true) is not allowed during Global Transaction.     ERRORCODE=-4201, SQLSTATE=2D521
at com.ibm.db2.jcc.am.fd.a(fd.java:679)
at com.ibm.db2.jcc.am.fd.a(fd.java:60)
at com.ibm.db2.jcc.am.fd.a(fd.java:120)
at com.ibm.db2.jcc.am.jb.setAutoCommit(jb.java:960)
at com.ibm.db2.jcc.am.df.setAutoCommit(df.java:158)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.atomikos.jdbc.AtomikosConnectionProxy.invoke(AtomikosConnectionProxy.java:161)
at $Proxy38.setAutoCommit(Unknown Source)
at org.apache.openjpa.lib.jdbc.DelegatingConnection.setAutoCommit(DelegatingConnection.java:167)
4

1 回答 1

0

我能够修复它。这里的问题是我们需要告诉 openJpa 参与 Atomikos 事务。这是附加属性()方法的更新版本:

@Bean
@DependsOn("transactionManager")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter,
                                                                   TransactionManager transactionManager) {
    final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource);
    em.setJtaDataSource(dataSource);
    em.setPackagesToScan("org.company.entity");
    em.setJpaVendorAdapter(jpaVendorAdapter);
    em.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
    em.setSharedCacheMode(SharedCacheMode.ALL);
    em.setJpaProperties(additionalProperties(dataSource, transactionManager));

    return em;
}


final Properties additionalProperties(DataSource dataSource, TransactionManager transactionManager) {
    final Properties openJpaProperties = new Properties();
    openJpaProperties.put("javax.persistence.transactionType", "JTA");
    openJpaProperties.put("openjpa.TransactionMode", "managed");
    openJpaProperties.put("openjpa.ConnectionFactoryMode", "managed");
    openJpaProperties.put("openjpa.ConnectionFactory", dataSource);
    openJpaProperties.put("openjpa.ManagedRuntime", "invocation(TransactionManagerMethod=com.atomikos.icatch.jta.TransactionManagerImp.getTransactionManager)");
    openJpaProperties.put("openjpa.MetaDataRepository", "Preload=true");
    openJpaProperties.put("openjpa.Compatibility", "QuotedNumbersInQueries=true");
    openJpaProperties.put("openjpa.ConnectionFactoryProperties", "PrettyPrint=true, PrettyPrintLineLength=80, PrintParameters=true");
    return openJpaProperties;
}
于 2015-06-16T19:53:50.517 回答