2012-01-23 25 views
0

我有一個事務性方法互相調用,但似乎事務提交之後它應該提交或至少出現插入日誌。這裏是呼叫層次結構:Spring Propagation.REQUIRES_NEW @Transaction commit只在外部事務結束後出現在日誌中

@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 (?, ?, ?, ?, ?, ?, ?) 

而不是從「存500行塊」方法返回後reveiving他們中的哪一個@Transactional(傳播= Propagation.REQUIRES_NEW):

@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

要應用@Transactional從而打開它,執行必須通過proxy來完成。

1

類的事務方法在沒有代理的情況下調用此類的其他事務方法,因此第二個方法事務不用於調用。

相關問題