我需要更新数据库中的数千条记录,但我想提交后,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和commit都不会产生错误。
发布于 2020-11-08 21:00:15
我遗漏了一条解决问题的重要信息。
我还有另一个公共方法,那就是从外部调用的方法。
public void reloadAttrs(TransDetail trans)
{
reloadAttrs();
}上面的方法实际上是使用默认事务传播,因为我没有特别提到它。由于这是第一个被调用的公共方法,spring忽略了被调用的下一个公共(异步)方法上的事务分界。我将上面的签名更改为:
@Transactional (propagation=Propagation.NOT_SUPPORTED)
public void reloadAttrs(TransDetail trans)
{
reloadAttrs();
}然后它就起作用了。每次提交后,我都能看到数据库中的更改。
https://stackoverflow.com/questions/64728277
复制相似问题