iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java锁竞争导致sql慢日志原因分析
  • 599
分享到

Java锁竞争导致sql慢日志原因分析

sql在Java代码中执行很慢Javasql慢日志 2022-11-21 22:11:49 599人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

线上在同步用户时,经常出现简单sql的慢日志。根据方法找到代码,发现方法内使用Redisson进行锁操作,waiTime和leaseTime都为3秒,数据库操作比较简单,只是一个简单

线上在同步用户时,经常出现简单sql的慢日志。根据方法找到代码,发现方法内使用Redisson进行操作,waiTime和leaseTime都为3秒,数据库操作比较简单,只是一个简单的用户更新操作。代码简化后如下

@Override
@Transactional(rollbackFor = Exception.class)
public LiveMemberResponseDTO becomeStudentNotQueryOrder(LiveBecomeStudentForOrderRequestDTO requestDTO) {
    EduUserEntity user = eduUserService.syncLocalByAccount(requestDTO.getOrderAccountId(), UserReGISterChannel.LIVE_APPLY);
    EduUserEntity applyUser = eduUserService.syncLocalByAccount(requestDTO.getApplyAccountId(), UserRegisterChannel.LIVE_APPLY);
    ...
    ...
    ...
}

调用了更新方法

@Override
@Lock(waitTime = 10000, leaseTime = 3000, value = RedisConstant.USER_SYNC_LOCAL, key = "#accountId")
public EduUserEntity syncLocalByAccount(String accountId, String mobile, String fullName, String source, UserRegisterChannel registerChannel) {
    EduUserEntity eduUserEntity = queryUsersByAccountId(accountId);
    boolean updateFlag = false;
    ....
	....
	....//判断是否需要更新
    if (updateFlag) {
       saveOrUpdate(eduUserEntity);
    }
    return eduUserEntity;
}

由于这里事务里面嵌套了redis锁,并且涉及到更新表,可能会有死锁的情况。通过在获取锁的地方打上地址获取到以下日志

可以看到[Thread-13]在等待了三秒后才获取到redis,根据获取锁的时机,列出表格

事务A(Thread-13)事务B(Thread-14)
获取redis锁
获取db锁
释放redis锁
获取redis锁
尝试获取db锁
尝试获取redis锁
等待三秒
redis锁超时,释放redis锁
成功获取redis锁
完成业务
释放redis和db锁
获取db锁

这是由于两次更新user表过程中,使用了一个事务A,导致事务B来获取db行锁的时候,被事务A阻塞。但在被事务A阻塞前,已经获取到了redis锁,所以导致事务A在获取第二次更新的redis锁的时候被阻塞,造成了死锁。

最终导致,redis锁超时,日志方面体现为慢sql,因为事务B的sql等待了三秒才拿到锁。

这种情况是因为事务和redis锁的嵌套导致,所以指定更新方法的事务传播等级为PROPAGATION_REQUIRED_NEW,不管外层是否存着事务,都开启新事务。

修改后代码

@Override
@Lock(waitTime = 10000, leaseTime = 3000, value = RedisConstant.USER_SYNC_LOCAL, key = "#accountId")
//这里开启新事务
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public EduUserEntity syncLocalByAccount(String accountId, String mobile, String fullName, String source, UserRegisterChannel registerChannel) {
    EduUserEntity eduUserEntity = queryUsersByAccountId(accountId);
    boolean updateFlag = false;
    ....
	....
	....//判断是否需要更新
    if (updateFlag) {
       saveOrUpdate(eduUserEntity);
    }
    return eduUserEntity;
}

声明式事务使用很简单,可以自动帮我们进行事务的开启、提交以及回滚等操作,但是事务的颗粒度是整个方法,无法进行精细化控制。在使用过程中要注意事务的范围与其他中间件的交互,通过指定适当的传播等级来达到效果。

到此这篇关于Java锁竞争导致sql慢日志原因分析的文章就介绍到这了,更多相关Java sql慢日志内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java锁竞争导致sql慢日志原因分析

本文链接: https://www.lsjlt.com/news/173278.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java锁竞争导致sql慢日志原因分析
    线上在同步用户时,经常出现简单sql的慢日志。根据方法找到代码,发现方法内使用redisson进行锁操作,waiTime和leaseTime都为3秒,数据库操作比较简单,只是一个简单...
    99+
    2022-11-21
    sql在Java代码中执行很慢 Java sql慢日志
  • 分析一些可能导致Golang速度变慢的原因
    随着云计算和大数据时代的到来,计算效率成为许多软件工程师面临的主要挑战之一。在这种情况下,Golang作为一种高效的编程语言,备受关注。然而,一些人声称Golang在处理某些情况下会变得异常缓慢。本文将分析一些可能导致Golang速度变慢的...
    99+
    2023-05-14
  • Java中ThreadLocal 导致内存 OOM 的原因分析
    目录原因分析正确的使用方式原因分析 ThreadLocal 导致内存 OOM 的原因是什么? ThreadLocal 底层通过 ThreadLocalMap 存储数据 源码如下:&n...
    99+
    2024-04-02
  • 一次因表变量导致SQL执行效率变慢的分析
    本篇内容主要讲解“一次因表变量导致SQL执行效率变慢的分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“一次因表变量导致SQL执行效率变慢的分析”吧!场景最近工作中,发现某同步JOB在执行中经常...
    99+
    2023-06-25
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作