Skip to content
Permalink
Browse files
BATCHEE-44 exceptions during rollback must not hide the real problem …
…exceptions

We now only log.error exceptions which happen during rollback but throw
the original Exception.
Prior to this change any Exception we got during rollback (e.g. if the connection
was already closed) did make us loose all the original Exception information.
  • Loading branch information
struberg committed Jul 9, 2014
1 parent b984c43 commit cd766e03270258133248a985940dc6c092805a4f
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 26 deletions.
@@ -59,11 +59,15 @@
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import static org.apache.batchee.container.util.Serializations.deserialize;
import static org.apache.batchee.container.util.Serializations.serialize;

public class JPAPersistenceManagerService implements PersistenceManagerService {
private final static Logger LOGGER = Logger.getLogger(JPAPersistenceManagerService.class.getName());

private static final String[] DELETE_QUERIES = {
StepExecutionEntity.Queries.DELETE_BY_INSTANCE_ID, CheckpointEntity.Queries.DELETE_BY_INSTANCE_ID,
JobExecutionEntity.Queries.DELETE_BY_INSTANCE_ID, JobInstanceEntity.Queries.DELETE_BY_INSTANCE_ID
@@ -83,8 +87,7 @@ public void cleanUp(final long instanceId) {
}
txProvider.commit(tx);
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -229,8 +232,7 @@ public void updateStepExecution(final long jobExecId, final StepContextImpl step
entity);
txProvider.commit(tx);
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -262,8 +264,7 @@ public StepExecutionImpl createStepExecution(final long jobExecId, final StepCon
stepExecution.setStepName(stepContext.getStepName());
return stepExecution;
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -378,8 +379,7 @@ public void updateWithFinalExecutionStatusesAndTimestamps(final long key, final
em.merge(instance);
txProvider.commit(tx);
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -423,8 +423,7 @@ public void markJobStarted(final long key, final Timestamp startTS) {
em.merge(instance);
txProvider.commit(tx);
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -504,8 +503,7 @@ public RuntimeFlowInSplitExecution createFlowInSplitExecution(final JobInstance
jobExecution.setLastUpdateTime(instance.getCreateTime());
return jobExecution;
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -538,8 +536,7 @@ public void updateBatchStatusOnly(final long executionId, final BatchStatus batc
em.merge(instance);
txProvider.commit(tx);
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -569,8 +566,7 @@ public RuntimeJobExecution createJobExecution(final JobInstance jobInstance, fin
jobExecution.setLastUpdateTime(execution.getCreateTime());
return jobExecution;
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -636,8 +632,7 @@ public JobInstance createJobInstance(final String name, final String apptag, fin
jobInstance.setJobName(name);
return jobInstance;
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -686,8 +681,7 @@ public void updateStepStatus(final long stepExecutionId, final StepStatus stepSt
em.merge(entity);
txProvider.commit(tx);
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -727,8 +721,7 @@ public void updateJobStatus(final long instanceId, final JobStatus jobStatus) {
}
txProvider.commit(tx);
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -745,8 +738,7 @@ public JobStatus getJobStatus(final long instanceId) {
setJobStatusData(status, em.find(JobInstanceEntity.class, instanceId));
txProvider.commit(tx);
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -800,8 +792,7 @@ public void setCheckpointData(final CheckpointDataKey key, final CheckpointData
}
txProvider.commit(tx);
} catch (final Exception e) {
txProvider.rollback(tx, e);
throw new BatchContainerRuntimeException(e);
throw new BatchContainerRuntimeException(performRollback(tx, e));
}
} finally {
emProvider.release(em);
@@ -846,4 +837,21 @@ public void init(final Properties batchConfig) {
}
emProvider.init(batchConfig);
}

/**
* Rollback the transaction and eventually log any exception during rollback.
* This method ensures that an Exception during rollback will *not* hide
* the original Exception!
*
* @return the original Exception
*/
private Exception performRollback(Object tx, Exception originalException) {
try {
txProvider.rollback(tx, originalException);
} catch (Exception exceptionDuringRollback) {
LOGGER.log(Level.SEVERE, "Got an Exception while rolling back due to another Exception. Printing Rollback Exception and re-throwing original one"
, exceptionDuringRollback);
}
return originalException;
}
}
@@ -19,9 +19,16 @@
import javax.persistence.EntityManager;
import java.util.Properties;

/**
* Abstracts away transaction handling for BatchEE tables itself.
* Mainly used in {@link org.apache.batchee.container.services.persistence.JPAPersistenceManagerService}
*/
public interface TransactionProvider {
Object start(EntityManager em);
void commit(Object o);


void rollback(Object tx, Exception e);

void init(Properties batchConfig);
}
@@ -37,6 +37,7 @@ public void commit(final Object o) {

@Override
public void rollback(final Object tx, final Exception e) {

EntityTransaction.class.cast(tx).rollback();
}

0 comments on commit cd766e0

Please sign in to comment.