JPA多次更新操作超时

时间:2017-05-19 02:02:57

标签: java jpa eclipselink

尝试对实体执行多次更新操作来执行长时间运行的过程,但事务会保持超时并回滚。

将日志记录设置为罚款的EclipseLink输出以下内容

    bind => [2 parameters bound]
Finest:   Execute query UpdateObjectQuery(entity.Service[ id=31 ])
Fine:   UPDATE service SET uid = ? WHERE (id = ?)
    bind => [2 parameters bound]
Finest:   Execute query UpdateObjectQuery(entity.Service[ id=32 ])
Fine:   UPDATE service SET uid = ? WHERE (id = ?)
    bind => [2 parameters bound]
Finest:   Execute query UpdateObjectQuery(entity.Service[ id=33 ])
Fine:   UPDATE service SET uid = ? WHERE (id = ?)
    bind => [2 parameters bound]
Finest:   Execute query UpdateObjectQuery(entity.Service[ id=34 ])
Fine:   UPDATE service SET uid = ? WHERE (id = ?)
    bind => [2 parameters bound]
Finest:   Execute query UpdateObjectQuery(entity.Service[ id=35 ])
Fine:   UPDATE service SET uid = ? WHERE (id = ?)
    bind => [2 parameters bound]
Finest:   Execute query UpdateObjectQuery(entity.Service[ id=36 ])
Fine:   UPDATE service SET uid = ? WHERE (id = ?)
    bind => [2 parameters bound]
Finest:   Execute query UpdateObjectQuery(entity.Service[ id=37 ])
Fine:   UPDATE service SET uid = ? WHERE (id = ?)
    bind => [2 parameters bound]
Finer:   end unit of work flush
Finer:   resume unit of work
Warning:   EJB5123:Rolling back timed out transaction [JavaEETransactionImpl: txId=6 nonXAResource=9 jtsTx=null localTxStatus=1 syncs=[com.sun.ejb.containers.ContainerSynchronization@70ec56d3, org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper$1@2f836809, org.eclipse.persistence.transaction.JTASynchronizationListener@7fa7baae, com.sun.enterprise.resource.pool.PoolManagerImpl$SynchronizationListener@74f86c98]] for [SearchManager]
Finer:   TX afterCompletion callback, status=ROLLEDBACK
Finest:   Connection released to connection pool [default].
Finer:   release unit of work
Finer:   client released

在更新操作期间调用以下三种方法

public void recreateIndex() {
    int start = 0;
    while (true) {
        List<Product> products = em.createNamedQuery("Product.findAll")
                .setMaxResults(100).setFirstResult(start).getResultList();
        indexProducts(products);
        start = products.get(products.size() - 1).getId();
        if (products.size() == 100) {
            start++;
        } else {
            start = 0;
            break;
        }
    }
    start = 0;
    while (true) {
        List<Service> services = em.createNamedQuery("Service.findAll")
                .setMaxResults(100).setFirstResult(start).getResultList();
        indexServices(services);
        start = services.get(services.size() - 1).getId();
        if (services.size() == 100) {
            start++;
        } else {
            break;
        }
    }
}

@Transactional
private void indexProducts(List<Product> products) {
    Map<String, Object> properties = em.getProperties();
    em.setProperty("javax.persistence.query.timeout", -1);
    for (Product p : products) {
        p.setUid(RandomStringUtils.randomAlphanumeric(10));
        addProduct(p);
        em.persist(p);
    }
    em.flush();
}

@Transactional
private void indexServices(List<Service> services) {
    em.setProperty("javax.persistence.query.timeout", -1);
    for (Service s : services) {
        s.setUid(RandomStringUtils.randomAlphanumeric(10));
        addService(s);
        em.persist(s);
    }
    em.flush();
}

我目前正在更新的两个表中的总行数等于1000行,但我希望它在生产中更多。如何在不使交易超时的情况下执行此操作。

我尝试的内容包括

  1. 在新的执行线程中运行代码(Fire and forget)它仍然超时
  2. 使用@TransactionManagement(TransactionManagementType.CONTAINER)
  3. 注释班级
  4. 尝试在没有事务的情况下运行我收到运行时错误,抱怨需要进行交易
  5. 尝试将javax.persistence.querytimeout设置为永不超时btw我不确定-1是否为无需超时所需的值。 这就是我
  6. 的地方

    如果需要,愿意发布更多代码。提前致谢

0 个答案:

没有答案