2012-01-23 27 views
0

私はお互いを呼び出すトランザクションメソッドを持っていますが、コミットすべき箇所の後にトランザクションがコミットするか、ここでは、コールhierachyは次のとおりです。Spring Propagation.REQUIRES_NEW @トランザクションコミットは、トランザクション終了後にのみログに表示されます

@Override 
@Transactional 
public DataProcessingStatistics copyInitialRevision() { 
    try { 
     DataProcessingStatistics statistics = new DataProcessingStatistics(); 
     transaction(statistics); 
     statistics.printResult(); 
     return statistics; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     throw new RuntimeException(e); 
    } 
} 

@Override 
@Transactional(propagation = Propagation.REQUIRES_NEW) 
public void transaction(DataProcessingStatistics statistics) { 
    entityAuditTableService.generateTables(statistics); 
    oneToManyRelationAuditTableService.generateTables(statistics); 
    manyToManyRelationAuditTableService.generateTables(statistics); 
} 

... 

@Service 
public class EntityAuditTableServiceImpl implements EntityAuditTableService { 
... 

@Override 
public void generateTables(DataProcessingStatistics statistics) { 
    List<EntityAuditTable> auditTables = loadAll(); 
    for (EntityAuditTable auditTable : auditTables) { 
     try { 
      statistics.addAsProcessed(auditTable, process(auditTable)); 
     } catch (Exception e) { 
      statistics.addAsSkipped(auditTable.getAuditTable(), e);    
     } 
    } 
} 

@Transactional(propagation = Propagation.REQUIRES_NEW) 
public int process(EntityAuditTable auditTable) { 
    EntityDataTable table = entityDataTableService.create(auditTable.getEntityDataTable().getEntityClass()); 
    List<EntityDataTableRow> rows = entityDataTableService.readAllData(table); 
    List<EntityAuditTableRow> auditTableRows = entityAuditTableRowService.generateTableData(auditTable, rows); 
    entityAuditTableRowService.saveAll(auditTableRows); 
    return auditTableRows.size(); 
} 

... 


@Service 
public class EntityAuditTableRowServiceImpl implements EntityAuditTableRowService { 

... 


@Override 
@Transactional 
public void saveAll(List<EntityAuditTableRow> auditTableRows) { 
    jdbcService.saveArraysAs500RowChunks(auditTableRows, new ListSaver<EntityAuditTableRow>(){ 
     @Override 
     public void save(List<EntityAuditTableRow> list) { 
      EntityAuditTableRowServiceImpl.this.saveJdbc(list); 
      for (EntityAuditTableRow auditTableRow: list) { 
       entityChangeService.saveFromRow(auditTableRow); 
      } 
     } 
    }); 
} 

... 


@Service 
public class JdbcServiceImpl implements JdbcService { 

@Override 
public <E> void saveArraysAs500RowChunks(List<E> rows, ListSaver<E> saver) { 
    for (int i = 0; i < rows.size(); i += 500) { 
     save500(rows.subList(i, Math.min(i +500, rows.size())), saver); 
    } 
} 

@Override 
@Transactional(propagation=Propagation.REQUIRES_NEW) 
public <E> void save500(final List<E> rows, ListSaver<E> saver) { 
    if (rows == null || rows.size() == 0) { 
     return; 
    } 
    if (rows.size() > 500) { 
     throw new IllegalStateException("(auditTableRows.size() > 500)"); 
    } 
    saver.save(rows); 
} 

... 

@Service 
public class EntityChangeServiceImpl implements EntityChangeService { 


@Override 
@Transactional 
public void saveFromRow(EntityAuditTableRow auditTableRow) { 
    Revision revision = revisionsService.load(auditTableRow.getAuditTableRow().getRevision().getId()); 
    EntityChange entityChange = create(auditTableRow); 
    save(entityChange); 
    revision.getEntitiesChanges().add(entityChange); 
    revisionsService.save(revision); 
} 

... 
@Service 
public class RevisionServiceImpl implements RevisionService { 

@Override 
@Transactional(propagation = Propagation.REQUIRES_NEW) 
public Revision create() { 
    Revision revisionEntity = createDetached(); 
    long generateNextIdForClass = idService.generateNextIdForClass(Revision.class); 
    revisionEntity.setId(generateNextIdForClass); 
    revisionEntity.setTimestamp(new Date()); 
    save(revisionEntity); 
    return revisionEntity; 
} 

@Override 
@Transactional 
public void save(Revision revisionEntity) { 
    persistenceManagerHibernate.save(revisionEntity); 
} 

ものであるだけで、私はENTITY_CHANGED_IN_REVISIONテーブルのログに挿入を受けるルート/初期メソッド呼び出し/ EntityChangeエンティティからの復帰後:

この時点:

@Override 
@Transactional 
public DataProcessingStatistics copyInitialRevision() { 
    try { 
     DataProcessingStatistics statistics = new DataProcessingStatistics(); 
     transaction(statistics); 
     statistics.printResult(); 
     return statistics; // only after that return insert log appear 
    } catch (Exception e) { 
     e.printStackTrace(); 
     throw new RuntimeException(e); 
    } 
} 

このログは唯一の復帰後に表示されます:

Hibernate: insert into ENTITY_CHANGED_IN_REVISION (ENTITY_ID, ENTITY_NAME, GROUP_ENTITY_ID, GROUP_NAME, REV_ID, REVISION_TYPE, ID) values (?, ?, ?, ?, ?, ?, ?) 

Hibernate: insert into ENTITY_CHANGED_IN_REVISION (ENTITY_ID, ENTITY_NAME, GROUP_ENTITY_ID, GROUP_NAME, REV_ID, REVISION_TYPE, ID) values (?, ?, ?, ?, ?, ?, ?) 

Hibernate: insert into ENTITY_CHANGED_IN_REVISION (ENTITY_ID, ENTITY_NAME, GROUP_ENTITY_ID, GROUP_NAME, REV_ID, REVISION_TYPE, ID) values (?, ?, ?, ?, ?, ?, ?) 

Hibernate: insert into ENTITY_CHANGED_IN_REVISION (ENTITY_ID, ENTITY_NAME, GROUP_ENTITY_ID, GROUP_NAME, REV_ID, REVISION_TYPE, ID) values (?, ?, ?, ?, ?, ?, ?) 

Hibernate: insert into ENTITY_CHANGED_IN_REVISION (ENTITY_ID, ENTITY_NAME, GROUP_ENTITY_ID, GROUP_NAME, REV_ID, REVISION_TYPE, ID) values (?, ?, ?, ?, ?, ?, ?) 

Hibernate: insert into ENTITY_CHANGED_IN_REVISION (ENTITY_ID, ENTITY_NAME, GROUP_ENTITY_ID, GROUP_NAME, REV_ID, REVISION_TYPE, ID) values (?, ?, ?, ?, ?, ?, ?) 

代わり@Transactional(伝播= Propagation.REQUIRES_NEW)である「500行のチャンクを保存する」方法から復帰した後、それらをreveivingの:@Transactionalを適用し、したがって、それを開くには

@Override 
@Transactional(propagation=Propagation.REQUIRES_NEW) 
public <E> void save500(final List<E> rows, ListSaver<E> saver) { 
    if (rows == null || rows.size() == 0) { 
     return; 
    } 
    if (rows.size() > 500) { 
     throw new IllegalStateException("(auditTableRows.size() > 500)"); 
    } 
    saver.save(rows); // invokes EntityChangeServiceImpl.saveFromRow 
} 

... 

@Service 
public class EntityChangeServiceImpl implements EntityChangeService { 


@Override 
@Transactional 
public void saveFromRow(EntityAuditTableRow auditTableRow) { 
    Revision revision = revisionsService.load(auditTableRow.getAuditTableRow().getRevision().getId()); 
    EntityChange entityChange = create(auditTableRow); 
    save(entityChange); 
    revision.getEntitiesChanges().add(entityChange); 
    revisionsService.save(revision); 
} 

答えて

0

、実行はproxyを介して行われなければなりません。

1

クラスのトランザクションメソッドは、このクラスの他のトランザクションメソッドをプロキシなしで呼び出すので、2番目のメソッドトランザクションは呼び出しで使用されません。

関連する問題