项目上有国密需求,对接第三方密码机对数据进行加解密,如数据机密性、完整性等,然后服务启动时得初始化好存量数据。刚开始没考虑那么多,就直接把还没初始化的数据查出来进行初始化,后来部署到现场测试环境之后,数据有几万条,密码、业务数据、用户重要数据、日志等都需要进行加密等处理,初始化太慢了,最重要的是,最后一条数据加密失败了,那么之后加密的那些全部失效了,因为还没提交事务。最后改为分批处理,多事务提交,互不影响,就算最后一批加密失败,不影响其他批次。这个就用到REQUIRES_NEW事务传播机制,开启新事物。
上代码:
@Autowired private TaskExecutor taskExecutor; private TransactionTemplate txTemplate; @Autowired public void setTxManager(PlatformTransactionManager txManager) { txTemplate = new TransactionTemplate(txManager); txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); } public void init() { List<UserInfo> userInfoList = findNotEncryptUserPassword(); //list分批 List<List<UserInfo>> partition = Lists.partition(userInfoList, 1000); for (List<UserInfo> list : partition) { //多线程、新事物处理加密、保存 taskExecutor.execute(() -> txTemplate.execute(s -> { for (UserInfo userInfo : list) { //处理密码加密初始化 userInfo.setUserPassword(hash(userInfo.getUserPassword(), userInfo.getUserId(),HashEncodeType.md5)); save(userInfo); } return null; })); } } |