批处理代码记录

关键词:jdbc读取数据库, 流式读取, spring管理事务,断点,保存点

对于数据量少的,比如几条sql就能完成的批量,可以用mybatis调用dao层来完成,对于数据量大,需要逐条处理的批量,需要在程序中创建jdbc连接,使用该连接一次批量执行sql,并借助PreparedStatement的预编译和批处理能力提高效率.批量中慎用 select ...for update,可能会产生表锁影响其他程序.

1 定义两个 Connection,一个用于查询sql的流式读取,一个用于出现异常后向异常日志表插入异常记录, Spring的DataDourceTransactionManager 用于管理事务,DataSource用于

获取连接

2 从断点记录表读取断点记录,这个表记录了每次commit成功后的最后一条记录,如果数据库在某次commit后挂掉,下次批处理可以从最后一次commit成功后开始跑,避免之前已提交的事务又重复执行

3 初始化查询sql,流式读取,每次取5000条,用DataDourceTransactionManager 开启事务,并从transactionSynchrobnizationManager获取用于记录错误数据的连接

4 while循环处理resultSet: 

  4.1 处理每条记录前先创建保存点: TransactionStatus.createSavaPoint(),

  4.2 对当前记录执行相应的增删改操作

  4.3 如果处理这条记录没有出现异常,则成功处理记录数加1,再释放保存点TransactionStatus.releaseSavePoint(saevPoint) ,如果出现异常就回滚至保存点TransactionStatus.rollbackToSavepoint(saevPoint),并向异常记录表插入异常记录

  4.3  每成功处理1000条记录,提交一次(DataSourceTransactionManeger.commit(transactionStatus)),并将本次提交的最后一条数据记录断点,用于下次断点重提(记录断点的方式就是往断点表插入当前这条记录的主键),并且重新开启事务

开事务代码:

复制代码
//定义事务
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
//定义隔离级别为读已提交
definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED) ;
//事务名称
definition.setName(xxx);
//事务传播方式
definition.setPropagetionBehavior(TransactionDefinition.PROPAGETION_REQUIRED);
//事务管理器开事务
transactionStatus = transactionManeger.getTransaction(definition);

复制代码

 

posted @   杨吃羊  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示