php小编西瓜在使用Spring Batch时,可能会遇到一个问题:当尝试同时启动两个或多个Spring Batch作业时,会抛出错误:ORA-08177: 无法序列化此事务的访问。这个错误可能让人困惑,但实际上它是由于数据库锁定问题导致的。在解决这个问题之前,我们需要了解一些关于Spring Batch和数据库事务的背景知识。
问题内容
尝试使用 completablefuture 并行运行两个 spring batch 作业时遇到错误。错误信息如下:
originalsql = insert into batch_job_instance(job_instance_id, job_name, job_key, version) values (?, ?, ?, ?) , error msg = ora-08177: can't serialize access for this transaction
我正在使用 spring batch 5.x、spring boot 3.1.6、jdk 17
应用程序属性
spring.batch.repository.isolationlevelforcreate=isolation_read_committed spring.batch.isolationlevel=read_committed spring.batch.jdbc.table-prefix=batch_ spring.batch.job.enabled=false
batchconfig.java
@configuration public class batchconfig { @bean("simpletaskexecutor") public taskexecutor simpletaskexecutor() { simpleasynctaskexecutor asynctaskexecutor = new simpleasynctaskexecutor("simpletaskexecutor"); asynctaskexecutor.setconcurrencylimit(concurrencycount); return asynctaskexecutor; } @bean("joblauncherasync") @scope("prototype") public joblauncher joblauncherasync(datasource datasource, jobrepository jobrepository) throws exception { taskexecutorjoblauncher joblauncher = new taskexecutorjoblauncher(); joblauncher.setjobrepository(jobrepository); joblauncher.settaskexecutor(simpletaskexecutor()); joblauncher.afterpropertiesset(); return joblauncher; } @bean public jpatransactionmanager transactionmanager(entitymanagerfactory entitymanagerfactory) { return new jpatransactionmanager(entitymanagerfactory); } @bean public batchjobexecutionlistener batchjobexecutionlistener() { return new batchjobexecutionlistener(); } @bean public batchjobstepexecutionlistner batchjobstepexecutionlistner() { return new batchjobstepexecutionlistner(); }
}
employeejobconfig.java
@configuration @import(batchconfig.class) public class employeejobconfig{ @autowired employeestatuswritter employeestatuswritter; @autowired employeependingprocessor employeependingprocessor; @bean("employeependingreader") public jpapagingitemreader<employee> employeependingreader(datasource ds,entitymanagerfactory entitymanagerfactory) { jpapagingitemreader<employee> jpareader = new jpapagingitemreader<>(); jpareader.setentitymanagerfactory(entitymanagerfactory); jpareader.setquerystring("select e from employee e"); jpareader.setpagesize(5000); return jpareader; } @bean("employeespinvokestep") public step employeespinvokestep(@qualifier("employeependingreader") itemreader<employee> reader, @qualifier("employeestatuswritter") itemwriter<employee> writer, @qualifier("employeependingprocessor") itemprocessor<employee, employee> processor,jobrepository jobrepository, platformtransactionmanager transactionmanager,batchjobstepexecutionlistner batchjobstepexecutionlistner,taskexecutor simpletaskexecutor) { return new stepbuilder("employeespinvokestep",jobrepository) .<employee, employee>chunk(50,transactionmanager).reader(reader) .processor(processor).writer(writer) .listener(batchjobstepexecutionlistner) .taskexecutor(simpletaskexecutor) .build(); } @bean("employeespjob") public job employeespjob(@qualifier("employeespinvokestep") step employeespinvokestep,jobrepository jobrepository,batchjobexecutionlistener batchjobexecutionlistener) { return new jobbuilder("employeespjob",jobrepository) .incrementer(new runidincrementer()) .listener(batchjobexecutionlistener) .start(employeespinvokestep) .build(); } }
managerconfig.java
@configuration @import(batchconfig.class) public class managerconfig { @autowired managerstatuswritter managerstatuswritter; @autowired managerpendingprocessor managerpendingprocessor; @bean("managerpendingreader") public jpapagingitemreader<manager> managerpendingreader(datasource ds,entitymanagerfactory entitymanagerfactory) { jpapagingitemreader<manager> jpareader = new jpapagingitemreader<>(); jpareader.setentitymanagerfactory(entitymanagerfactory); jpareader.setquerystring("select m from manager m"); jpareader.setpagesize(5000); return jpareader; } @bean("managerspinvokestep") public step indvinvoiceconsctlspinvokestep(@qualifier("managerpendingreader") itemreader<manager> reader, @qualifier("managerstatuswritter") itemwriter<manager> writer, @qualifier("managerpendingprocessor") itemprocessor<manager, manager> processor,jobrepository jobrepository, platformtransactionmanager transactionmanager,batchjobstepexecutionlistner batchjobstepexecutionlistner,taskexecutor simpletaskexecutor) { return new stepbuilder("managerspinvokestep",jobrepository) .<manager, manager>chunk(5000,transactionmanager).reader(reader) .processor(processor).writer(writer) .listener(batchjobstepexecutionlistner) .taskexecutor(simpletaskexecutor) .build(); } @bean("managerspjob") public job managerspjob(@qualifier("managerspinvokestep") step indvinvoiceconsctlspinvokestep,jobrepository jobrepository,batchjobexecutionlistener batchjobexecutionlistener) { return new jobbuilder("managerspjob",jobrepository) .incrementer(new runidincrementer()) .listener(batchjobexecutionlistener) .start(indvinvoiceconsctlspinvokestep) .build(); } }
batchjobmanager.java
@service public class batchjobmanager { @autowired applicationcontext context; @autowired batchexecutorservice batchexecutorservice; @autowired batchjobrunner batchjobrunner; public void startjob() { try { system.out.println("batchjobmanager called .. "+new date()); string[] invoicenames={"employeespjob","managerspjob"}; list<string> invoicenameslist = arrays.aslist(invoicenames); launchasyn(getbatchjoblist(invoicenameslist)); } catch (exception e) { system.out.println("while loading job.."); e.printstacktrace(); } } public list<batchjob> getbatchjoblist(list<string> jobnames) throws exception{ list<batchjob> batchjoblist=new arraylist<batchjob>(); for(string job:jobnames) { batchjob batchjob= batchjob.builder().jobname(invoicejob).build(); batchjoblist.add(batchjob); } return batchjoblist; } public void launchasyn( list<batchjob> batchjoblist) throws exception{ list<completablefuture<batchjob>> batchjobfuturelist = new arraylist<completablefuture<batchjob>>(); for(batchjob batchjob:batchjoblist) { completablefuture<batchjob> jobfuture = batchexecutorservice.execute(batchjob, asynctaskexecutor); batchjobfuturelist.add(jobfuture); } completablefuture<void> jobfutureresult = completablefuture .allof(batchjobfuturelist.toarray(new completablefuture[batchjobfuturelist.size()])); completablefuture<list<canbatchjob>> allcompletablefuture = jobfutureresult.thenapply(future -> { return batchjobfuturelist.stream().map(completablefuture -> completablefuture.join()) .collect(collectors.tolist()); }); list<batchjob> resultfuturelist=allcompletablefuture.get(); for(batchjob batch:resultfuturelist) { system.out.println("status "+batch.getiscompleted()); } } }
batchexecutorservice.java
@service public class batchexecutorservice { @autowired batchjobrunner batchjobrunner; public completablefuture<canbatchjob> execute(canbatchjob canbatchjob,taskexecutor threadpooltaskexecutor){ return completablefuture.supplyasync(() -> batchjobrunner.execute(canbatchjob),threadpooltaskexecutor); } }
batchjobrunner.java
@service public class batchjobrunner { @autowired applicationcontext context; @autowired @qualifier("joblauncherasync") joblauncher joblauncherasync; /* * @autowired joblauncher joblauncherasync; */ public batchjob execute(batchjob batchjob) { try { system.out.println(" batchjob"+batchjob.getjobname()+" called ..."); joblauncherasync.run(getjob(batchjob.getjobname()), getjobparameters(batchjob.getjobname())); thread.sleep(15000); batchjob.setiscompleted(true); system.out.println(" batchjob"+batchjob.getjobname()+" completed ..."); } catch(exception e) { system.out.println("exception "+e.getmessage()); batchjob.seterrordesc(e.getmessage().tostring()); e.printstacktrace(); } return canbatchjob; } public job getjob(string jobname) { return (job) context.getbean(jobname); } public jobparameters getjobparameters(string jobname) { jobparameters jobparameters = new jobparametersbuilder() .addstring("unique_id", uuid.randomuuid().tostring(), true) .addstring("job_name", jobname, true) .adddate("execution_start_date", date.from(instant.now()), true).tojobparameters(); return jobparameters; } }
batchjob.java
public class BatchJob { private String jobName; private Boolean isCompleted; private String errorDesc; }
作业在逐一或按顺序执行时成功运行。但是,在使用 completablefuture 时,遇到了问题。同时启动 spring 批处理作业是正确的方法吗?
解决方法
1.将以下属性添加到application.properties
spring.main.allow-bean-definition-overriding=true
2.更新了 joblauncher(),如下 batchconfig.java 中所示
@bean("joblauncher") public joblauncher joblauncher(datasource datasource, jobrepository jobrepository) throws exception { taskexecutorjoblauncher joblauncher = new taskexecutorjoblauncher(); joblauncher.setjobrepository(jobrepository); joblauncher.settaskexecutor(simpletaskexecutor()); joblauncher.afterpropertiesset(); return joblauncher; }
-
删除了 completablefuture。
-
删除了 batchexecutorservice.java
-
在 batchjobmanager.java 中添加了以下方法来调用作业。
public void launchSync(List<BatchJob> batchJobList) throws Exception { for(BatchJob batchJob:batchJobList) { batchJobRunner.execute(batchJob); } }
以上是尝试同时启动两个或多个 Spring Batch 作业时,会抛出错误:ORA-08177: 无法序列化此事务的访问的详细内容。更多信息请关注PHP中文网其他相关文章!

steam四月份上线的游戏不少,很多小伙伴都在期待这些游戏的上线,但是却是遇见了各种错误代码的问题,如错误代码101和错误代码-105的问题,这会让大家错过好多活动,为此杨莉娜特意整理出来了解决这些问题的方法,大家可以用来解决问题。steam错误代码101解决办法steam商店错误代码-105解决办法解决方法一:手动修改DNS我们可以手动修改DNS来解决这些错误代码的问题,大家不要觉得修改DNS很麻烦,其实很简单的,首先第一步就是右键点击电脑中的本地网络,然后双击ipv4,这样就可以直接进入到属

在当今信息泛滥的时代,隐私保护变得尤为重要。为了帮助用户更好地保护个人隐私,OPPO手机提供了多种隐藏应用的方法。作为备受大众喜爱的手机品牌之一,OPPO手机让你的隐私无处可寻。本文将详细介绍几种OPPO手机隐藏应用的方法及操作步骤。使用应用双开功能隐藏应用用户可以将需要隐藏的应用安装在另一个账号中、OPPO手机提供了应用双开功能,从而实现应用的隐匿,可以同时登录两个相同应用的账号、通过这一功能。具体操作步骤为:进入设置-应用分身-选择需要隐藏的应用-创建分身账号-安装隐藏应用。通过应用锁隐藏应

视频卡是一种特殊的电路板,用于控制计算机监视器上显示的内容。它也称为图形处理单元(GPU),可为Linux游戏和其他用途计算3D图像和图形。让我们看一下解决问题的7大LinuxGPU监视和诊断命令行工具。以下工具在Linux上可用于GPU监视和诊断目的,以及其他操作系统(例如FreeBSD)上运行。如今,大多数Linux和FreeBSD用户都使用Nvidia,Intel和AMDGPU。LinuxGPU监控和诊断命令行工具我们可以使用以下工具来监视、诊断和检查基于Linux或*BSD的系统。获得图

尝试使用completablefuture并行运行两个springbatch作业时遇到错误。错误信息如下:originalsql=insertintobatch_job_instance(job_instance_id,job_name,job_key,version)values(?,?,?,?),errormsg=ora-08177:can'tserializeaccessforthistransaction我正在使用spring

作者丨TimAnderson编译丨诺亚出品|51CTO技术栈(微信号:blog51cto)Zed编辑器项目目前仍处于预发布阶段,已在AGPL、GPL和Apache许可下开源。该编辑器以高性能和多种AI辅助选择为特色,但目前仅适用于Mac平台使用。内森·索博(NathanSobo)在一篇帖子中解释道,Zed项目在GitHub上的代码库中,编辑器部分采用了GPL许可,服务器端组件则使用了AGPL许可证,而GPUI(GPU加速用户界面)部分则采用了Apache2.0许可。GPUI是Zed团队开发的一款

古籍有载,四方鼓声起,是为鼓仙现世,将助苍生脱离病痛。患者受其恩泽,复归健康,更因此延年益寿……那些民间传说总喜欢像这样杜撰一个奇幻的开头。今天给大家带来了阿姐鼓3游戏攻略全部图解,阿姐鼓3图文大全分享,想要了解阿姐鼓3第一章、第二章、第三章、第四章、第五章攻略的朋友速来!第一章第二章第三章第四章第五章阿姐鼓3游戏攻略全部图解阿姐鼓3第一章攻略1、阿姐鼓3第一章问医需要先使用钥匙打开抽屉。2、车头里面箱子的秘密是11037。3、用撬棍去售票处把盒子拉出来,获得剪刀,再用剪刀把娃娃剪开获得钥匙,用

作为一名Linux爱好者,我们经常会遇到一些需要自己手动安装的软件或配置,而在CentOS系统上安装jemalloc和无线网卡也是常见的需求,本文将为您详细介绍如何在CentOS系统上安装jemalloc和无线网卡。CentOS安装jemallocjemalloc是一种高效的内存分配器,可以提高程序的性能,下面是在CentOS系统上安装jemalloc的步骤:1.打开终端,使用root用户登录系统。2.使用以下命令安装依赖库:```yuminstall-ygccgcc-c++automake3.

我有一个名为libmylibrary.a的文件和一个名为mylibrary.h的头文件其中包含一个名为myfunction()的函数。我将它们与cpp文件(helloworldjni.cpp)结合起来,创建了一个名为native.dll的新库。但是,当我尝试使用jni在java中编译native.dll时,我无法找到libmylibrary.a和mylibrary.h中的函数。mylibrary.h//mylibrary.h#ifndefmylibr

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)