I'm using jberet implementation of JSR 352 java batch specs.
Actually I need a separate transaction for doing a singular update, something like this:
class MyItemWriter implements ItemWriter
@Inject
UserTransaction transaction
void resetLastProductsUpdateDate(String uidCli) throws BusinessException {
try {
if (transaction.getStatus() != Status.STATUS_ACTIVE) {
transaction.begin();
}
final Customer customer = dao.findById(id);
customer.setLastUpdate(null);
customer.persist(cliente);
transaction.commit();
} catch (RollbackException | HeuristicMixedException | HeuristicRollbackException | SystemException | NotSupportedException e) {
logger.error("error while updating user products last update");
throw new BusinessException();
}
}
I first tried marking resetLastProductsUpdateDate methoad as @Transactional(REQUIRES_NEW), however it didn't worked.
My question is:
- Is there any more elegant way to achieve this singular transaction without manually handle of transaction?
- While does UserTransation works, EntityManager.transaction doesn't. I don't get it why.
Class below, which is injected from a Batchlet, works properly; Why I can't get to make work the @Transactional annotation on resetLastProductsUpdateDate method instead?
public class DynamicQueryDAO { @Inject EntityManager entityManager; @Inject private Logger logger; @Transactional(Transactional.TxType.REQUIRED) public void executeQuery(String query) { logger.info("executing query: {}", query); final int output = entityManager.createNativeQuery(query).executeUpdate(); logger.info("rows updated: {}", output); }
}
EDIT
Actually I guess neither usertransaction is a good solution, because it affects entire itemwriter transaction management. Still Don't know how to deal with transaction isolation :(