Spring Roo项目作为没有事务的批处理作业

时间:2011-01-12 14:13:30

标签: java spring transactions spring-roo

我有一个Roo项目,它对事务工作“很好”,但是每个.merge()或.persist()需要的时间越来越长,所以应该花费10ms才能在事务结束时花费5000ms。幸运的是,我的更改是单独的幂等的,所以我真的不需要交易。

但是当我抛出事务处理时,当我执行myObject.merge()

时,我遇到了经典的“上下文已经关闭”

我正在运行的作业是作为批处理命令行,所以这是我通常做的事情:

public static void main(final String[] args) {
    context = new ClassPathXmlApplicationContext("META-INF/spring/applicationContext.xml");
    JpaTransactionManager txMgr = (JpaTransactionManager) context.getBean("transactionManager");
    TransactionTemplate txTemplate = new TransactionTemplate(txMgr);
    txTemplate.execute(new TransactionCallback() { @SuppressWarnings("finally")
    public Object doInTransaction(TransactionStatus txStatus) {
    try {
        ImportUnitFromDisk importer = new ImportUnitFromDisk();
        int status = importer.run(args[0]);
        System.out.println("Import data complete status: " + status);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        return null;
    }
    }});

    System.out.println("All done!");
    System.exit(0);
}

但我真正想做的是这样的事情:

public static void main(final String[] args) {
    ImportUnitFromDisk importer = new ImportUnitFromDisk();
    int status = importer.run(args[0]);
    System.out.println("Import data complete status: " + status);
    System.out.println("All done!");
    System.exit(0);
}

如果使用Spring Roo(使用OpenJPA和MySQL)生成实体,我可以做什么来允许我在不使用事务的情况下持久化()和merge()?

干杯

的Nik

2 个答案:

答案 0 :(得分:1)

即使您的更改是幂等的,您仍然需要交易。

就表现而言。

  1. 您的实体对象的紧密耦合程度。 (例如,如果所有表fk引用都迁移到实体关系,那么它非常紧密耦合)?

  2. 您可能应该删除一些不需要的双向关系。

  3. 识别主表并删除映射到主记录的实体。

  4. 您的级联选项是什么?检查您是否在所有地方都有级联。

  5. 对我而言,实体地图看起来太紧密了。(每个人都知道有人......)并且级联选项开始合并整个对象图。 (记录你的jpa sql,这可以验证我的假设)

答案 1 :(得分:1)

我遇到了与Spring / Hibernate批处理完全相同的性能问题。请注意,这与Spring Roo甚至Spring无关 - 这是由于Hibernate / JPA的工作原理。

基本问题是Hibernate维护了作为事务一部分的所有Java实体的会话缓存,对于新实体(没有完成字节码检测),Hibernate必须扫描每次刷新的实体以查看是否有更新。对于会话中的n =新实体,这至少是O(n)。如果批处理主要是添加新实体,那么这将成为整个批处理的O(n ^ 2)行为。

如果要在一个事务中维护整个过程,一个解决方案是定期刷新(执行插入/更新),然后逐出不再需要保留在会话中的实体。另一种解决方案是将批处理拆分为多个事务。

有关详细信息,请参阅http://www.basilv.com/psd/blog/2010/avoiding-caching-to-improve-hibernate-performance