title: Spring Propagation.REQUIRES_NEW @Transaction commit appears in log only after outter transaction end
body: <p>I have a transactional methods invoking each other but it seems that transaction commits after the spot it should commit or at least insertion logs appear after that. Here is the call hierachy:</p>
  
  <pre><code>@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&lt;EntityAuditTable&gt; 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&lt;EntityDataTableRow&gt; rows = entityDataTableService.readAllData(table);
      List&lt;EntityAuditTableRow&gt; auditTableRows = entityAuditTableRowService.generateTableData(auditTable, rows);
      entityAuditTableRowService.saveAll(auditTableRows);
      return auditTableRows.size();
  }
  
  ...
  
  
   @Service
   public class EntityAuditTableRowServiceImpl implements EntityAuditTableRowService {
  
  ...
  
  
  @Override
  @Transactional
  public void saveAll(List&lt;EntityAuditTableRow&gt; auditTableRows) {
      jdbcService.saveArraysAs500RowChunks(auditTableRows, new ListSaver&lt;EntityAuditTableRow&gt;(){
          @Override
          public void save(List&lt;EntityAuditTableRow&gt; list) {
              EntityAuditTableRowServiceImpl.this.saveJdbc(list);
              for (EntityAuditTableRow auditTableRow: list) {
                  entityChangeService.saveFromRow(auditTableRow);
              }
          }
      });
  }
  
  ...
  
  
  @Service
  public class JdbcServiceImpl implements JdbcService {
  
  @Override
  public &lt;E&gt; void saveArraysAs500RowChunks(List&lt;E&gt; rows, ListSaver&lt;E&gt; saver) {
      for (int i = 0; i &lt; rows.size(); i += 500) {
          save500(rows.subList(i, Math.min(i +500, rows.size())), saver);
      }
  }
  
  @Override
  @Transactional(propagation=Propagation.REQUIRES_NEW)
  public &lt;E&gt; void save500(final List&lt;E&gt; rows, ListSaver&lt;E&gt; saver) {
      if (rows == null || rows.size() == 0) {
          return;
      }
      if (rows.size() &gt; 500) {
          throw new IllegalStateException("(auditTableRows.size() &gt; 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);
  }
  </code></pre>
  
  <p>The thing is only after the return from the root/initial method call i receive inserts in logs for ENTITY_CHANGED_IN_REVISION table/EntityChange entity:</p>
  
  <p>this point:</p>
  
  <pre><code>@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);
      }
  }
  </code></pre>
  
  <p>this logs appears only after return:</p>
  
  <pre><code>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 (?, ?, ?, ?, ?, ?, ?)
  </code></pre>
  
  <p>Instead of reveiving them after return from "save 500 row chunk" method which is @Transactional(propagation=Propagation.REQUIRES_NEW):</p>
  
  <pre><code>@Override
  @Transactional(propagation=Propagation.REQUIRES_NEW)
  public &lt;E&gt; void save500(final List&lt;E&gt; rows, ListSaver&lt;E&gt; saver) {
      if (rows == null || rows.size() == 0) {
          return;
      }
      if (rows.size() &gt; 500) {
          throw new IllegalStateException("(auditTableRows.size() &gt; 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);
  }
  </code></pre>