Spring数据JdbcTemplate不提交

问题描述

我需要更新数据库中的数千条记录,但我想在一批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,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(),但是直到整个公共方法完成后,数据库才反映该提交。如何确保每次提交后确实将数据写入数据库。提交也不会给出任何错误

解决方法

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

我还有另一种公开方法,就是从外面叫。

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

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

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

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