在Java批处理中处理单独的事务(JSR-352)

问题描述 投票:0回答:1

我正在使用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),但是没有用。

我的问题是:

  1. 在没有手动处理交易的情况下,还有其他更优雅的方式来实现此单一交易吗?
  2. 虽然UserTransation可以正常工作,但EntityManager.transaction无效。我不明白为什么。
  3. 下面的类是从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);
    }
    

    }

编辑

实际上,我认为用户事务都不是一个好的解决方案,因为它会影响整个项目编写者的事务管理。仍然不知道如何处理事务隔离:(

java-ee-7 jsr352 jberet
1个回答
0
投票

通常,批处理应用程序应避免直接处理事务。您可以使批处理组件在某些情况下引发一些业务异常,并配置job.xml以触发对此业务异常的重试。重试期间,每个单独的数据都将以其自己的块进行处理和提交。

© www.soinside.com 2019 - 2024. All rights reserved.