我正在使用JSR 352 Java批处理规范的jberet实现。
实际上,我需要一个单独的事务来执行单个更新,如下所示:
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();
}
}
我首先尝试将resetLastProductsUpdateDate方法标记为@Transactional(REQUIRES_NEW),但是没有用。
我的问题是:
下面的类是从Batchlet注入的,它可以正常工作;为什么我不能在resetLastProductsUpdateDate方法上使用@Transactional注释呢?
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);
}
}
编辑
实际上,我认为用户事务都不是一个好的解决方案,因为它会影响整个项目编写者的事务管理。仍然不知道如何处理事务隔离:(
通常,批处理应用程序应避免直接处理事务。您可以使批处理组件在某些情况下引发一些业务异常,并配置job.xml以触发对此业务异常的重试。重试期间,每个单独的数据都将以其自己的块进行处理和提交。