@Transactional(rollbackFor = Exception.class)
@Override
public void vehiclePortrait() {
log.info("车辆画像统计开始");
List<OverloadVehicleInfo> overloadVehicleInfos = vehicleInfoDao.findAll();
if (CollectionUtils.isNotEmpty(overloadVehicleInfos)) {
overloadVehicleInfoCacheDao.deleteAll();
List<OverloadVehicleInfoCache> overloadVehicleInfoCaches = Lists.newArrayList();
for (OverloadVehicleInfo overloadVehicleInfo : overloadVehicleInfos) {
OverloadVehicleInfoCache overloadVehicleInfoCache = new OverloadVehicleInfoCache();
BeanMapper.copy(overloadVehicleInfo, overloadVehicleInfoCache);
overloadVehicleInfoCaches.add(overloadVehicleInfoCache);
}
List<List<OverloadVehicleInfoCache>> lists = ListUtil.partition(overloadVehicleInfoCaches, listSize);
log.info("车辆画像统计共执行:{}次", lists.size());
int i = 0;
for (List<OverloadVehicleInfoCache> overloadVehicleInfoCacheList : lists) {
log.info("车辆画像统计第{}次", ++i);
overloadVehicleInfoCacheDao.saveAll(overloadVehicleInfoCacheList);
// long count = overloadVehicleInfoCacheDao.count();
// System.out.println("count: " + count);
}
}
log.info("车辆画像统计结束");
}
此方法执行结束后(共写入38000多条数据),两分钟后才查询出数据。原因是:
当一个事务提交时:
- **重做日志(Redo Log)**会被立即或按配置策略写入磁盘,确保事务的改动可以被恢复。
- 数据页可能还在内存的缓冲池(如InnoDB的Buffer Pool)中,并不一定立即刷盘。数据库系统会根据各种策略(如Checkpoint机制)决定何时将缓冲池中的脏页(已修改但未写回磁盘的页面)写入磁盘。
也就是说,事务提交成功后,只代表数据已经写入到了Redo Log,但还未写入到磁盘中,这中间有两分钟的时间差。