批处理代码记录
关键词: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);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通