当前位置: 首页 > news >正文

wordpress 下载站wordpress网址改坏了

wordpress 下载站,wordpress网址改坏了,网上商城网站建设解决方案,网站推广 教程一次mysql死锁的排查过程一、背景17号晚上要吃饭了#xff0c;看旁边的妹子和佐哥还在调代码#xff0c;就问了下什么问题啊#xff0c;还在弄#xff0c;妹子说#xff0c;在测试环境测试给用户并发发送卡券时#xff0c;出现了死锁#xff0c;但看代码没有死锁#x…一次mysql死锁的排查过程一、背景17号晚上要吃饭了看旁边的妹子和佐哥还在调代码就问了下什么问题啊还在弄妹子说在测试环境测试给用户并发发送卡券时出现了死锁但看代码没有死锁问题如下图看日志确实发生了死锁按照死锁产生的原因一般死锁是两把锁两个人争抢每个人都获得其中一把谁都不让谁等待对方释放锁死循环导致的图示如下不过这次说看代码没有问题感觉这个问题比较诡异跟他们说先吃饭吃完一起群力群策研究研究这个。二、问题点1. ### SQL: select * from score_user where user_id ? for update这个sql查询是发送了死锁三、排查过程1. 根据经验和死锁产生的条件猜测代码并发执行一个线程先锁住了表A的记录另外一个线程由于原因没有线索表A记录而锁住了表B的记录接下来锁住A记录的线程等待B的锁是否锁住B的线程等待A的锁释放所以产生了原因所以先看代码2. 代码如下面所示可以看到基本逻辑都是先插入score_gain_streamJava代码  Transactional(propagation  Propagation.REQUIRED, isolation  Isolation.READ_COMMITTED,rollbackFor  Exception.class)public boolean generateScoreInfo(String userId, Integer score,Long scoreRuleId, int scoreType, int scoreStatus, String scoreWay,String orderId, String inviteeId, String reqId, Integer eventVersion) {//0:参数判断if(null  score || score  0) {log.warn(score null or return true;}//1:获取用户等级int memberLevel  MemberLevel.GENERAL_MEMBER;ScoreUser dbScoreUser  scoreUserManager.getScoreUserByUserIdForUpdate(userId);boolean isCreate  null  dbScoreUser ? true : false;if (!isCreate) {memberLevel  dbScoreUser.getMemberLevel();}// 2:构造/生成积分流水ScoreGainStream scoreGainStream  contructSocreGainStream(userId, score, scoreRuleId, scoreType, scoreStatus, scoreWay,orderId, inviteeId, reqId, eventVersion,memberLevel);boolean streamFlag  addScoreGainStream(scoreGainStream);if(!streamFlag){log.error(addScoreGainStream error,data:  scoreGainStream.toString());return false;}// 3:判断用户类型if(isCreate){//新增积分用户信息try {boolean addFlag  addScoreUser(userId, memberLevel, scoreType, score);if(!addFlag){log.error(generateScoreInfo addScoreUser error, userId:  userId  |  score:  score );throw new RuntimeException(generateScoreInfo addScoreUser error);}} catch (Exception e) {if(e instanceof DuplicateKeyException){log.warn(addScoreUser DuplicateKeyException,userId:  userId  |  score:  score);//查询用户信息ScoreUser updateUser  contructUpdateScoreUser(scoreUserManager.getScoreUserByUserIdForUpdate(userId), score, scoreStatus);boolean flag  scoreUserManager.updateUserScoreInfoById(updateUser)  0 ? true : false;if(!flag){log.error(generateScoreInfo updateUserScoreInfoById error, data:  updateUser.toString());throw new RuntimeException(generateScoreInfo updateUserScoreInfoById error);}return true;}else{log.error(addScoreUser error,userId:  userId  |  score:  score, e);return false;}}return true;}else{//更新积分用户信息ScoreUser updateScoreUser  contructUpdateScoreUser(dbScoreUser, score, scoreStatus);boolean flag  scoreUserManager.updateUserScoreInfoById(updateScoreUser)  0 ? true : false;if(!flag){log.error(generateScoreInfo updateUserScoreInfoById error, data:  updateScoreUser.toString());throw new RuntimeException(generateScoreInfo updateUserScoreInfoById error);}return true;}}3. 看代码不会发生死锁的多个线程同时在执行每个线程都开启事务每个线程都加锁查询score_user,发现都没有查询到那么每个线程都执行插入score_gain_stream操作都成功接下来进行插入score_user,这里面只有一个线程可以成功有唯一主键其他线程这里会报错接下来代码抓取异常进行加锁查询此时报错死锁了4. 理论上报错这里没有涉及争抢资源的情况大家都在等待score_user释放就一个锁怎么会死锁呢看来代码解决不了问题了5. 再去查下mysql的死锁日志看看死锁具体怎么产生的如下图链接如何查询死锁日志http://825635381.iteye.com/blog/2339503看紫色中的三部分TRANSACTION 1292943095需要RECORD LOCKS space id 553 page no 376 n bits 368 index index_user_id of table tbj.score_user这个位置的X锁一直等待这个X锁TRANSACTION 1292943097这个已经持有RECORD LOCKS space id 553 page no 376 n bits 368 index index_user_id of table tbj.score_user这个位置的S锁这样导致TRANSACTION 1292943095无法在这个位置获得X锁TRANSACTION 1292943097这个事务接下来也在RECORD LOCKS space id 553 page no 376 n bits 368 index index_user_id of table tbj.score_user这个位置的等待X锁所以问题点有了 1. 为什么有一个线程会持有S锁看前面的代码结构没有加过S锁2. 还有为什么TRANSACTION 1292943097这个事务不能继续加X锁提交6.这边开始排查为什么会有S锁查了很多资料终于在官网文档查询到了如下[b]Java代码  INSERT sets an exclusive lock on the inserted row. This lock is an index-record lock, not a next-key lock (that is, there is no gap lock) and does not prevent other sessions from inserting into the gap before the inserted row.Prior to inserting the row, a type of gap lock called an insertion intention gap lock is set. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap.If a duplicate-key error occurs, a shared lock on the duplicate index record is set. This use of a shared lock can result in deadlock should there be multiple sessions trying to insert the same row if another session already has an exclusive lock.大体的意思是insert会对插入成功的行加上排它锁这个排它锁是个记录锁而非next-key锁(当然更不是gap锁了)不会阻止其他并发的事务往这条记录之前插入记录。在插入之前会先在插入记录所在的间隙加上一个插入意向gap锁(简称I锁吧)并发的事务可以对同一个gap加I锁。如果insert 的事务出现了duplicate-key error 事务会对duplicate index record加共享锁。这个共享锁在并发的情况下是会产生死锁的比如有两个并发的insert都对要对同一条记录加共享锁而此时这条记录又被其他事务加上了排它锁排它锁的事务提交或者回滚后两个并发的insert操作是会发生死锁的。[/b]原理分析这就找到上面问题为什么加上S锁的问题当并发插入时出现duplicate异常时mysql会默认加上S锁这就是为什么会出现死锁日志里面有个事务加上S锁了也就同时解释了第二个问题为什么事务没能提交因为第一个事务也发生了duplicate异常同时也对同一个位置加上了S锁这样就出现了一种情况多个线程对同一个位置持有S锁每个线程都去这个位置争抢X锁S和X锁两者是互斥关系所以出现循环等待死锁就此产生关于mysql锁的机制单独写个博客来介绍四、解决办法1. 并发插入时不在一个事务内进行再次事务提交2. 通过其他手段如预创建账户解决这个要并发插入的问题3. 改并发为串行执行五、解决过程六、问题总结1. mysql并发插入出现duplicate时会默认加S锁这个坑啊坑啊要研究下为什么这么加七、为什么会发生1. 知识体系需要再次完善技术无止境
http://wiki.neutronadmin.com/news/228957/

相关文章:

  • 网站费用多少网站怎么做移动图片
  • 做VIP视频网站赚钱支付宝手机网站支付二维码怎么做
  • 网站开发外包方案阿里云域名注册官网登录
  • 冕宁住房和建设局网站永久个人网站
  • 如何自己网站接装修生意做北京建设网站合同下载
  • 如何创建刷单网站上海优化排名网站
  • 网站建设上机考试深圳有做网站的吗
  • 福建住房和城乡建设网站网站建设用宝塔
  • 一个做外汇的网站叫熊猫什么的素材网免费
  • 机械网站怎么做discuz 转 wordpress
  • 消费者联盟网站怎么做一站式免费建站平台
  • 山东济南城乡建设厅网站wordpress 注册不了
  • 网站建设煊煊网网站开发我能做什么
  • 营销网站建站公司wordpress在线时间代码
  • 网站app生成软件开封到濮阳
  • 制作视频网站建设包头seo推广哪家专业
  • 杭州建设网 工程信息网站wordpress如何抓取
  • 做网站资质荣誉用的图片公司做的网站如何开启伪静态
  • 网站如何防止别人抄袭易语言如何做网站登录
  • 网站建设用什么软件做浏览器下载安装2023最新版
  • 做网站必须要购买空间吗网站后台修改网站首页怎么做
  • 网站优化排名教程河南项目备案信息网
  • 沈阳建站模板wordpress贝宝插件
  • 温州本地网站平台做盗版网站违法吗
  • 网站建设需要准备什么软件个人博客wordpress
  • seo如何根据网站数据做报表河南企业做网站
  • 网站开发实例社区学校 网站建设招聘
  • 网站的建设方面广州财税公司排行榜
  • 网站建设需求分析流程图wordpress 获取插件目录下
  • 汕头网站建设推广交换链接网站