Spring Batch DataSourceTransactionManager fails on Oracle

这一生的挚爱 提交于 2019-12-22 19:25:14

问题


I'm using WebLogic 10.3.3 with Oracle 11g and face a weird problem with Spring Batch as soon as I'm switching from Spring ResourcelessTransactionManager (which is mainly for testing) to the productive DataSourceTransactionManager. First I used WebLogics default driver oracle.jdbc.xa.client.OracleXADataSource but this one fails because Spring can't set the isolation level - this is also documented here.

I'm fine with that since I don't need global transactions anyway so I switched to oracle.jdbc.driver.OracleDriver. Now I'm getting the error message

ORA-01453: SET TRANSACTION must be first statement of transaction

I don't find a lot of information on this, there was a bug but that should have been fixed in Oracle 7 long time ago. It looks like a transaction is started before (?) the actual job gets added to the JobRepository and is not closed properly or something like that.


回答1:


JobI was able to solve this by setting the Isolation level for all transactions to READ_COMMITTED. By default, Spring sets that to SERIALIZABLE which is very strict (but perfectly fine). This didn't work on my machine although Oracle should support it:

http://www.oracle.com/technetwork/issue-archive/2005/05-nov/o65asktom-082389.html

Here's my code - first for the configuration:

<bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
    <property name="transactionManager" ref="transactionManager" />
    <property name="dataSource" ref="dataSource" />
    <property name="isolationLevelForCreate" value="ISOLATION_READ_COMMITTED" />
</bean>

...and this is for the job itself (simplified):

public class MyFancyBatchJob {
  @Transactional(isolation=Isolation.READ_COMMITTED)
  public void addJob() {
    JobParameters params = new JobParametersBuilder().toJobParameters();
    Job job = jobRegistry.getJob("myFancyJob");
    JobExecution execution = jobLauncher.run(job, params);
  }
}



回答2:


<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
  <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
  <property name="url" value="jdbc:oracle:thin:<username>/<password>@<host>:1521:<sid>" /> 
</bean> 

  <jdbc:initialize-database data-source="dataSource">
    <jdbc:script location="org/springframework/batch/core/schema-drop-oracle10g.sql" /> 
    <jdbc:script location="org/springframework/batch/core/schema-oracle10g.sql" />
  </jdbc:initialize-database> 

  <bean id="jobRepository"
    class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="transactionManager" ref="transactionManager" />
    <property name="databaseType" value="oracle" />
     <property name="tablePrefix" value="BATCH_"/>
        <property name="isolationLevelForCreate" value="ISOLATION_DEFAULT"/>
  </bean>

  <bean id="jobLauncher"
    class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository" />
  </bean>

/*for spring batch with oracle 10g and 11g 
*/


来源:https://stackoverflow.com/questions/16036536/spring-batch-datasourcetransactionmanager-fails-on-oracle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!