我们有一个spring引导应用程序,它的起点是一个API。API调用一个接口,比如ITradeService,它实现了Callable。ITradeService有一个方法服务(),它依次调用7个方法,其中最后三个说method5() method6()和method7()是独立的。
在SIT,UAT环境中,由于某些原因,4个节点中只有一个节点是活动的,我的项目领导要求我使用4个线程- 1个线程执行服务方法,其他3个线程执行上述3个方法。
我们的项目中有三个图层
- 控制器(Rest API)
- 服务ITradeService
TradeServiceImpl
Type1TradeServiceImplType2TradeServiceImplType3TradeServiceImpl - DAO CommonDao Type1Dao Type2Dao Type3Dao
我们在每个DAO类中使用JdbcTemplate。
在应用程序中。我们已经将hikari数据库连接池配置为2
当我尝试使用ThreadPoolTaskExecutor执行4个请求的线程时,该进程按预期工作,但当我发送第5个请求时,它说
CannotCreateTransactionException无法为事务打开JDBC连接
我知道这4个线程持有JDBC连接。我应该让线程释放JDBC连接并将其发送回hikari连接池或我应该在任务完成时关闭线程
我应该怎么做,在春天的特定方式?
理解为什么您觉得需要并行运行这三个方法是有帮助的。
在任何情况下,你都可以通过以下方式解决/缓解这个问题:
- 设置适当的
connectionTimeout
和maximumPoolSize
,以确保池自动扩展以满足应用程序的需求,或者额外的线程在等待连接被释放时不会超时,和/或 - 确保在执行这三个方法期间打开连接的时间尽可能短,例如,线程在
@Transactional
方法中没有进行繁重的计算,文件访问等。
关于第二个要点,如果您绝对需要原子操作,也许您可以使用乐观锁定(取出您需要的信息并完成那里的工作单元,在数据的分离副本上执行繁重的工作,启动另一个工作单元,查看数据是否在此期间更改,如果更改,重试整个过程,否则仅使用您的副本更新数据)。