首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring-data JdbcTemplate不提交

Spring-data JdbcTemplate不提交
EN

Stack Overflow用户
提问于 2020-11-07 21:42:21
回答 1查看 71关注 0票数 0

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

代码语言:javascript
复制
@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和commit都不会产生错误。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-08 21:00:15

我遗漏了一条解决问题的重要信息。

我还有另一个公共方法,那就是从外部调用的方法。

代码语言:javascript
复制
public void reloadAttrs(TransDetail trans)
{
    reloadAttrs();
}

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

代码语言:javascript
复制
@Transactional (propagation=Propagation.NOT_SUPPORTED)
public void reloadAttrs(TransDetail trans)
{
    reloadAttrs();
}

然后它就起作用了。每次提交后,我都能看到数据库中的更改。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64728277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档