最近在做业务的时候,发现有个接口莫名的超时,跟踪代码发现,在更新数据库的时候,一直处于死锁状态。这段更新数据库的代码时放在了parallelstream中。
环境
sprintboot + druid连接池 + mybatis
先说说出现这种问题的解决办法吧
1、最简单的办法就是将parallelstream改成stream,由并行改为串行
2、在进行增删改的时候,尽量使用单独的数据库连接来避免线程间的竞争,可以使用连接池来管理,并为每个线程分配独立的连接。
3、如果需要并行执行增删改,可以在同一个事务中对数据库进行操作避免多线程之间同一个链接的竞争,并且保证原子性
4、可以考虑将数据拆分为多个部分,让每个线程处理不同的部分,避免线程之间的竞争造成死锁。
造成这个问题的原因
其实就是parallelstream会将数据分成多个子任务,然后多线程处理这些子任务的时候,每个线程都会区尝试获取数据库连接,这时候,就会导致线程间的竞争和死锁。
另外
如果只是查询操作的话,通常是不会出现死锁问题的,因为查询操作部队数据库进行写操作,不同查询对同一个数据库连接不会相互干扰。但是如果是高并发场景的话,就要考虑数据库连接的性能瓶颈了。需要合理的规划好查询频率和并发控制。