一、死锁问题背景

在收据批量打印时,由于采用异步并发触发打印,同时触发打印(九千多数据 每隔50ms触发一次),导致了并发执行引起在接口更新打印次数时postgresql发生死锁问题,

具体报错如下:

1 ### The error occurred whilesetting parameters2 ### SQL: update t_sc_receipt set print_num = coalesce(print_num,0) + 1 ,print_ts=?

3 ### Cause: org.postgresql.util.PSQLException: ERROR: deadlock detected4 详细:Process 19540 waits for ShareLockon transaction 12520113; blocked by process 19539.5 Process 19539 waits for ShareLock on transaction 12520112; blocked by process 19540.6 建议:See server log forquery details.7 在位置:while rechecking updated tuple (329,3) in relation "t_sc_receipt"

8 ; SQL []; ERROR: deadlock detected9 详细:Process 19540 waits for ShareLock on transaction 12520113; blocked by process 19539.10 Process 19539 waits for ShareLock on transaction 12520112; blocked by process 19540.11 建议:See server log forquery details.12 在位置:while rechecking updated tuple (329,3) in relation "t_sc_receipt"; nested exception is org.postgresql.util.PSQLException: ERROR: deadlock detected13 详细:Process 19540 waits for ShareLock on transaction 12520113; blocked by process 19539.14 Process 19539 waits for ShareLock on transaction 12520112; blocked by process 19540.15 建议:See server log forquery details.16 在位置:while rechecking updated tuple (329,3) in relation "t_sc_receipt"

17 at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:263)18 at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)19 at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)20 at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:368)21 at com.sun.proxy.$Proxy57.update(Unknown Source)22 at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:254)23 at com.xxx.framework.mybatis.dao.impl.MyBatisDaoImpl.updateBySql(MyBatisDaoImpl.java:531)24 at com.xxx.dscsettle.receipt.ReceiptService.updatePrintNum(ReceiptService.java:160)25 at com.xxx.dscsettle.receipt.ReceiptService$$FastClassBySpringCGLIB$$82e91731.invoke()26 at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)27 at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:651)28 at com.xxx.dscsettle.receipt.ReceiptService$$EnhancerBySpringCGLIB$$67b6a353.updatePrintNum()29 at com.alibaba.dubbo.common.bytecode.Wrapper72.invokeMethod(Wrapper72.java)30 at com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:46)31 at com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:72)32 at com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:53)33 at com.onlyou.framework.log.DubboLogServiceFilter.invoke(DubboLogServiceFilter.java:28)34 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)35 at com.alibaba.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:64)36 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)37 at com.alibaba.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:42)38 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)39 at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:75)40 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)41 at com.alibaba.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:78)42 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)43 at com.alibaba.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:61)44 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)45 at com.alibaba.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:132)46 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)47 at com.alibaba.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38)48 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)49 at com.alibaba.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:38)50 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69)51 at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:98)52 at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:98)53 at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:170)54 at com.alibaba.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:52)55 at com.alibaba.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:81)56 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)57 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)58 at java.lang.Thread.run(Thread.java:745)59 Caused by: org.postgresql.util.PSQLException: ERROR: deadlock detected60 详细:Process 19540 waits for ShareLock on transaction 12520113; blocked by process 19539.61 Process 19539 waits for ShareLock on transaction 12520112; blocked by process 19540.62 建议:See server log for query details.

二、原因分析

从报错的提示我们知道了在数据库postgresql发生了死锁(ERROR: deadlock detected  侦测到了死锁发生),而且可以定位是在并发更新打印次数的时候发生的,正常的逻辑下,分页去不断更新收据的打印次数应该是不会出错的,在这边批量更新打印次数时出现了错误。

1.死锁是由于资源的相互竞争引起的,在update数据的时候应该是数据库行锁导致的

2.因为批量修改是一个默认的事务,所以如果没有全部修改完,索引是不会被放开的,所以才会在并发的多次访问中出现死锁,

3.研究出现问题的原因,发现最可能得是重复的行锁导致的,最终才查出原因是因为代码逻辑的原因,未传更新idList,而sql当中又进行了空的判断,导致每次都去更新全部的表数据,由于不同事务直接的相互等待,得不到资源,导致了死锁。

三、问题解决与拓展

批量更新的死锁解决方案有以下两种

1.将批量update通过for循环改成单条修改,但是这个方法对服务器的压力增大

2.在更新数据的时候进行一次筛选,将重复的数据剔除出去

在本次问题解决当中,只需将代码中传入正确的idLIst即可解决问题,因为本身进行迭代是没有进行重复upadate的。

疑问:并发update下postgresql就会出现shareLock死锁吗?

一般情况下的多次update应该不会导致死锁,而在事务当中的update则比较可能发生死锁现象。

同时,也看到了一位博主说postgresql 并发update的死锁问题可能是一些版本出现的bug,以及可能可以进行解决的设置以下两个参数进行解决:

autovacuum_vacuum_scale_factor = 0.03

autovacuum_analyze_scale_factor = 0.03

postgresql 并发访问_postgresql 并发update下导致的死锁问题相关推荐

  1. postgresql 并发访问_PostgreSQL并发控制(显式锁定)

    基于PostgreSQL 9.4 四.显式锁定 PostgreSQL提供了多种锁模式用于控制对表中数据的并发访问.这些模式可以用于在MVCC无法给出期望行为的场合.同样,大多数PostgreSQL命令 ...

  2. php并发访问mysql_php并发对MYSQL造成压力的解决方法_PHP

    PHP页面有一个浏览量统计每秒有200并发,造成insert给mysql造成很大压力 lnmp环境,其他页面内容都做了缓存了,没有多大的负载,就是这个浏览量统计功能,给mysql带来不小的压力,请问诸 ...

  3. java并发访问_Java并发访问

    1 线程安全 线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用.不会出现数据不一致或者数据污染. 线程不安全就 ...

  4. 29 | 无锁的原子操作:Redis如何应对并发访问?

    文章目录 Redis核心技术与实战 实践篇 29 | 无锁的原子操作:Redis如何应对并发访问? 并发访问中需要对什么进行控制? Redis 的两种原子操作方法 Redis核心技术与实战 实践篇 2 ...

  5. ios并发会造成什么问题_iOS Core data多线程并发访问的问题

    大家都知道Core data本身并不是一个并发安全的架构:不过针对多线程访问带来的问题,Apple给出了很多指导:同时很多第三方的开发者也贡献了很多解决方法.不过最近碰到的一个问题很奇怪,觉得有一定的 ...

  6. php-cgi和php-fpm,Windows环境下解决Nginx+php并发访问阻塞问题。

    php-cgi 是运行php, php-fpm是守护php-cgi进程 nginx配置目录运行php         location  ~ \.php$         {              ...

  7. 大规模集群下Hadoop NameNode如何承载每秒上千次的高并发访问

    目录 一.问题源起 二.HDFS优雅的解决方案 (1)分段加锁机制 + 内存双缓冲机制 (2)多线程并发吞吐量的百倍优化 (3)缓冲数据批量刷磁盘 + 网络的优化 四.总结 五.参考文章 一.问题源起 ...

  8. [转]高并发访问下避免对象缓存失效引发Dogpile效应

    避免Redis/Memcached缓存失效引发Dogpile效应 Redis/Memcached高并发访问下的缓存失效时可能产生Dogpile效应(Cache Stampede效应). 推荐阅读:高并 ...

  9. EF Core下利用Mysql进行数据存储在并发访问下的数据同步问题

    小故事 在开始讲这篇文章之前,我们来说一个小故事,纯素虚构(真实的存钱逻辑并非如此) 小刘发工资后,赶忙拿着现金去银行,准备把钱存起来,而与此同时,小刘的老婆刘嫂知道小刘的品性,知道他发工资的日子,也 ...

最新文章

  1. matlab将孤立点连接起来,复杂网络模型的matlab实现
  2. c语言(int)x 100,【单选题】下列语句执行后,变量a、c的值分别是( ) int x=182; int a,c;c=x/100;a=x%10;...
  3. ios查看线程数量_关于iOS多线程,你看我就够了(已更新)
  4. Nginx 简单命令
  5. 雷军:电视机越大才越舒服!
  6. mysql课件_MYSQL讲课时的PPT课件.ppt
  7. 模型融合之stacking和blending
  8. 构造函数SimpleAdapter()
  9. wxWindows 程序编译选项设置统揽
  10. java 歌词解析代码_网易云歌词爬取(java)
  11. CSND博客☞盘码之路开始
  12. 美国服务器查询网站查询网站查询网站查询网站查询,全球DNS节点查询网
  13. 树莓派 vnc Cannot currently show the desktop
  14. php 模拟登陆微信,微信公众平台模拟登陆有关问题
  15. 爱和感恩2021年末记
  16. Unity Timeline的使用
  17. 2018ACM-ICPC焦作站 补题
  18. 物体检测及分类方法总结(提供了很多论文和代码链接)
  19. 【pen200-lab】10.11.1.115
  20. 判断处理器是大端模式还是小端模式

热门文章

  1. 中标麒麟kylinV10操作系统无法识别光驱,插入光驱没反应
  2. 电子工程可以报考二建_我是电子信息工程专业,可以报考二级建造师吗?要..._二建考试_帮考网...
  3. javax.servlet.ServletException: Could not resolve view with name ‘***‘ in servlet
  4. 实习,内推,校招,社招的区别和联系
  5. eQTL | Expression quantitative trait loci | 表达数量性状基因座 | QTL | 数量性状位点
  6. 一篇难得的关于傅里叶分析的好文
  7. 极路由 刷linux,极路由1s刷openwrt不完全教程
  8. mac删除分区并合并分区
  9. 微信小游戏从零开始申请软著到上线
  10. SQL语句增删改查公司-员工3表典型案例