JBeret skippable exception thrown in ItemWriter triggers new chunk within the old transaction

164 Views Asked by At

Using JBeret I execute a simple job with single chunk based step which reads entries from the database, processes them and updates it. The step also defines a ChunkListener which interacts with the database as well and a list of skippable exception classes.

An example of such a job is:

<job id="testJob" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
  <step id="test">
    <listeners>
      <listener ref="someChunkListener"/>
    </listeners>
    <chunk item-count="1" >
      <reader ref="testReader" />
      <processor ref="testProcessor"/>
      <writer ref="testWriter"/>
      <skippable-exception-classes>
        <include class="java.lang.IllegalStateException"/>
      </skippable-exception-classes>
    </chunk>
  </step>
</job>

I have observed the following flow:

  1. Transaction has been started for the chunk
  2. The someChunkListener beforeChunk is triggered
  3. The ItemReader is triggered
  4. The ItemProcessor is triggered
  5. *The ItemWriter is triggered causing an IllegalStateException
  6. *The someChunkListener beforeChunk is triggered
  7. The ItemReader is triggered on new chunk
  8. ...

What I found strange is that between step 5) and step 6) no new transaction is started, but a new chunk has started/the chunk has restarted.

I tried looking into the JSR-352 specification, but I could not find such behavior described. I looked at the pseudo codes provided there, but I could not find a single pseudo code which suggests that a new chunk may be started (beforeChunk on the chunk listener may be called) but the old transaction is used. I also looked at the JBeret implementation of ChunkRunner and it seems that the prevention of starting of a new transaction is intentional.

To me it seems natural that in this situation either no beforeChunk callback would be called (we continue in the same chunk) or a new transaction would exist for our chunk.

I'm worried that I cannot find a well specified transaction boundaries on chunk based jobs. How should I handle possible dirty transactions based on partially written items or updates from the chunk listeners or even sending a JMS messages via XA Transaction?

Is this behavior JBeret behavior described somewhere along with other similar behavior? Is it a bug, or something JSR-352 specific I didn't look at?

1

There are 1 best solutions below

11
cheng On

I think what you are seeing may have to do with the item-count = 1 in your job xml file. Since every single item has its own chunk, so a new chunk is started after skipping, hence calling the beforeChunk listener method.

Also because in the first chunk, the skippable exception caused the item to be skipped. As a result, there is nothing left to be committed, and active transaction continues onto the next iteration.

See Jakarta Batch spec skippable exception section.

This batch spec issue may be somewhat related.