I try to use Spring Batch in JSR 352 mode in Websphere. (Websphere 8.0, Spring Batch 3.0.1)
As far as I understand the documentation, spring should handle the transactions, i.e. begin a transaction before calling the ItemReader of a step, committing the transactions after calling the ItemWriter, etc.
However, in my case no transaction is active when the ItemReader is called (userTransaction.getStatus() == 6). My code works if I start the transaction myself in the itemReader, but my understanding is that I shouldn't have to do that.
I suspect the problem is in the way I set up my batch.
This is a sample code that shows the problem:
META_INF/batch.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<tx:jta-transaction-manager />
</beans>
META-INF/batch-jobs/samplebatch3.xml:
<?xml version="1.0" encoding="UTF-8"?>
<job version="1.0"
id="samplebatch3"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd">
<step id="step1">
<chunk checkpoint-policy="item"
item-count="5">
<reader ref="my.jbatchtest.samplebatch3.SampleReader" />
<processor ref="my.jbatchtest.samplebatch3.SampleProcessor"/>
<writer ref="my.jbatchtest.samplebatch3.SampleWriter" />
</chunk>
</step>
</job>
The ItemReader:
package my.jbatchtest.samplebatch3;
import java.io.Serializable;
import javax.batch.api.chunk.ItemReader;
import javax.naming.InitialContext;
import javax.transaction.UserTransaction;
import org.xadisk.connector.outbound.XADiskConnectionFactory;
public class SampleReader implements ItemReader {
private UserTransaction utx;
public SampleReader() {
// TODO Auto-generated constructor stub
}
@Override
public void open(Serializable checkpoint) throws Exception {
utx = (UserTransaction) new InitialContext().lookup("jta/usertransaction");
System.out.println("Status before begin:"+utx.getStatus());
utx.begin();
System.out.println("Status after begin:"+utx.getStatus());
}
@Override
public void close() throws Exception {
// TODO Auto-generated method stub
}
@Override
public Object readItem() throws Exception {
// TODO Auto-generated method stub
return null;
}
@Override
public Serializable checkpointInfo() throws Exception {
// TODO Auto-generated method stub
return null;
}
}
The debugging output from the ItemReader:
[07.10.14 12:52:48:881 CEST] 00000039 SystemOut O Status before begin:6
[07.10.14 12:52:48:881 CEST] 00000039 SystemOut O Status after begin:0
My questions are:
- is my understanding correct, that spring batch should manage the transactions?
- then why doesn't it do so?