【问题标题】:Spring-data JdbcTemplate does not commitSpring-data JdbcTemplate 不提交
【发布时间】:2020-11-07 13:42:20
【问题描述】:

我需要更新数据库中的数千条记录,但我想在一批 5000 条记录后提交。

@Service
@Transactional (rollbackFor=Throwable.class)
public class AttributeProcessorServiceImpl extends DataLoader implements 
                  AttributeProcessorService
{
    .....
    private final TransactionTemplate transTemplate;
    private final JdbcTemplate jdbcTemplate;
    @Autowired private PlatformTransactionManager platformTransactionManager;

    @Autowired
    public BlockAttributeProcessorServiceImpl( 
        TransactionTemplate transTemplate,
        JdbcTemplate jdbcTemplate,
        .....)
    {
        super();
        this.transTemplate = transTemplate;
        this.jdbcTemplate=jdbcTemplate;
        .....
    }

    @Async
    @Transactional (propagation=Propagation.NOT_SUPPORTED)
    public void reloadAttrs()
    {
        loadAttrs();
        updateAttrs();
    }

    private void loadAttrs()
    {
         ...some data fetching and processing, finally call db update.
         updateDbInBatches(rowcount, sql);
    }

    private void updateAttrs()
    {
         ...some data fetching and processing, finally call db update.
         updateDbInBatches(rowcount, sql);
    }

    private void updateDbInBatches(long rowcount, String sql)
    {
        DefaultTransactionDefinition def;
        boolean hasMore=true;
        Integer from;
        Integer to = 0;
        int batchSize=5000; //gets from property

        while (hasMore)
        {
            from = to+1;
            to = batchSize;

            def = new DefaultTransactionDefinition();
            def.setName("backCommitTx");
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
            TransactionStatus status = platformTransactionManager.getTransaction(def);
  
            int rows = jdbcTemplate.update(sql,paramValues,paramTypes);
            logger.debug("Loaded ["+rows+"] records.");
            platformTransactionManager.commit(status);

            if (to > rowcount)
            {
                hasMore=false;
                logger.debug("All records ["+rowcount+"] updated.");
            }
        }
    }
}

如果我在 loadAttrs() 之后放置一个断点,它会显示它已将一堆记录加载到数据库并发出了 commit(),但数据库不会反映该提交,直到整个公共方法完成后。我如何确保每次提交后确实将数据写入数据库。 commit 也没有给出任何错误。

【问题讨论】:

    标签: spring-boot spring-data spring-jdbc jdbctemplate


    【解决方案1】:

    我错过了解决问题的重要信息。

    我有另一个从外部调用的公共方法。

    public void reloadAttrs(TransDetail trans)
    {
        reloadAttrs();
    }
    

    上面的方法实际上是使用默认的事务传播,因为我没有特别提到它。由于这是第一个被调用的公共方法,spring 忽略了下一个被调用的公共(异步)方法的事务划分。我将上面的签名更改为:

    @Transactional (propagation=Propagation.NOT_SUPPORTED)
    public void reloadAttrs(TransDetail trans)
    {
        reloadAttrs();
    }
    

    然后它起作用了。每次提交后我都能看到数据库中的变化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-25
      • 1970-01-01
      • 2019-05-30
      • 1970-01-01
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      • 2020-07-30
      相关资源
      最近更新 更多