深入理解mysql中的各种超时属性

1. 前言

connectTimeout: 连接超时
loginTimeout: 登录超时
socketTimeout: Socket网络超时,即读超时
queryTimeout: sql执行超时
transactionTimeout:spring事务超时
innodb_lock_wait_timeout:innodb锁等待超时
netTimeoutForStreamingResults:mysql server网络回包写超时(针对大量数据查询的sql)

2 connectTimeout和loginTimeout

mysql数据库在建立连接时,会在connectTimeout 、loginTimeout这两个变量中的取其之一作为真正的连接超时属性,具体取值逻辑是在com.mysql.cj.protocol.StandardSocketFactory#connect建立连接时调用的getRealTimeout方法。

在这里插入图片描述
在这里插入图片描述
getRealTimeout方法的expectedTimeout参数值是connnectTimeout.
getRealTimeout的逻辑是如果loginTimeout有值(this.loginTimeoutCountdown > 0)且[connnectTimeout没值(this.loginTimeoutCountdown > 0)或connnectTimeout值大于loginTimeout]则取值loginTimeout,否则取值connnectTimeout。也就是说这个方法取值思路是:两者都有值时,在两者中取较小的那个值作为最终的连接超时时间,两者中只有一个有值时,取有值那个参数作为最终的连接超时时间。
既然说到这儿了,那么我们应该搞清楚connnectTimeout loginTimeout这两个参数的来源是在哪儿?

1) loginTimeout

loginTimeout参数来源于驱动管理器的loginTimeout ,在com.mysql.cj.jdbc.ConnectionImpl#connectOneTryOnly方法中可以看到这个取值逻辑。

在这里插入图片描述

貌似我们没有给驱动管理器设置过登录超时这参数,DriverManager#loginTimeout的默认值是0,不应该是30。
其实这DriverManager#loginTimeout现在的值是HikariCP连接池给我们设的默认值。HikariPool构造方法中初始化执行PoolBase#initializeDataSource时调用setLoginTimeout去给DriverManager设置登录超时
在这里插入图片描述
在这里插入图片描述
上面PoolBase#setLoginTimeout(DataSource)方法中的dataSource 参数是com.zaxxer.hikari.util.DriverDataSource类的实例,而com.zaxxer.hikari.util.DriverDataSource#setLoginTimeout(int) 方法就是会直接给DriverManager的loginTimeout设值。

//com.zaxxer.hikari.util.DriverDataSource
  @Override
   public void setLoginTimeout(int seconds) throws SQLException
   {
      DriverManager.setLoginTimeout(seconds);
   }

从下面的代码可以看出,PoolBase#connectionTimeout属性值来源于HikariConfig#connectionTimeout,而HikariConfig#connectionTimeout的属性值又来源于配置文件中的spring.datasource.hikari.connection-timeout属性值,若配置文件中的此属性值为空,则取默认值30秒

  PoolBase(final HikariConfig config)
   {
      this.config = config;
      //....
      //PoolBase#connectionTimeout来自HikariConfig#connectionTimeout
      this.connectionTimeout = config.getConnectionTimeout();
      this.validationTimeout = config.getValidationTimeout();
      this.lastConnectionFailure = new AtomicReference<>();
	//....
      initializeDataSource();
   }
public class HikariConfig implements HikariConfigMXBean
{
   private static final Logger LOGGER = LoggerFactory.getLogger(HikariConfig.class);

   private static final char[] ID_CHARACTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
   private static final long CONNECTION_TIMEOUT = SECONDS.toMillis(30);
   private static final long VALIDATION_TIMEOUT = SECONDS.toMillis(5);
   private static final long IDLE_TIMEOUT = MINUTES.toMillis(10);
   private static final long MAX_LIFETIME = MINUTES.toMillis(30);
   /**
    * Default constructor
    */
   public HikariConfig()
   {
      dataSourceProperties = new Properties();
      healthCheckProperties = new Properties();

      minIdle = -1;
      maxPoolSize = -1;
      maxLifetime = MAX_LIFETIME;
      //默认值30秒
      connectionTimeout = CONNECTION_TIMEOUT;
      validationTimeout = VALIDATION_TIMEOUT;
      idleTimeout = IDLE_TIMEOUT;
      initializationFailTimeout = 1;
      isAutoCommit = true;

      String systemProp = System.getProperty("hikaricp.configurationFile");
      if (systemProp != null) {
         loadProperties(systemProp);
      }
   }
}

在这里插入图片描述

2) connectTimeout

connectTimeout参数因为是在com.mysql.cj.conf.PropertyKey com.mysql.cj.conf.PropertyDefinitions类中定义的,它的默认值是0,即表示可以无限时长地连接等待;所以它需要在配置文件jdbc连接属性spring.datasource.url上设值,如jdbc:mysql://localhost:3306/{xx_db}?connectTimeout={numTime}

在这里插入图片描述
在这里插入图片描述

3. socketTimeout

socketTimeout是socket超时时间,即读超时。它在om.mysql.cj.conf.PropertyKey com.mysql.cj.conf.PropertyDefinitions`类中定义,默认值是0,它也是在jdbc连接url上配置。
在这里插入图片描述

在这里插入图片描述
的socketTimeout在com.mysql.cj.protocol.a.NativeSocketConnection#connect 方法中真正得以应用,本质上就是为Socket为SO_TIMEOUT选项设值,tcp/ip协议底层对SO_TIMEOUT提供了支持,这跟应用层mysql协议无关。而queryTimeout netTimeoutForStreamingResults参数都是应用层mysql协议对它的支撑。
在这里插入图片描述
在这里插入图片描述

4 queryTimeout

queryTimeout: sql执行超时。jdbc规范的Statement定义了这个超时时间(见java.sql.Statement#setQueryTimeout接口方法)
如果使用原生的jdbc,则需要手动调用ava.sql.Statement#setQueryTimeout设置sql执行超时。
国内实际上一般都使用mybatis这个orm框架,我们可以在配置文件中用mybatis.configuration.default-statement-timeout配置全局默认的queryTimeout,当然也可以在指定的Mapper方法中单独配置queryTimeout(优先级比mybatis.configuration.default-statement-timeout高)
在这里插入图片描述
mybatis框架 BaseStatementHandler#prepare中调用setStatementTimeout设值sql超时时间。
其逻辑是先取当前指定Statement的queryTimeout,若没有则取全局默认的queryTimemout。然后把此值跟spring事务注解@Transactional配置的事务超时时间进行比较,最终的queryTimeout取两者中较小的那个值。
在这里插入图片描述

//StatementUtil
public static void applyTransactionTimeout(Statement statement, Integer queryTimeout, Integer transactionTimeout) throws SQLException {
   if (transactionTimeout == null) {
     return;
   }
   if (queryTimeout == null || queryTimeout == 0 || transactionTimeout < queryTimeout) {
     statement.setQueryTimeout(transactionTimeout);
   }
 }

接下来来看看queryTimeout的实现原理,ClientPreparedStatement#executeInternal方法在执行sql之前会调用startQueryTimer尝试获取一个CancelQueryTask超时任务 ,在执行完sql后尝试取消这个超时任务的,如果在超时前完成了sql查询,这时任务就被成功取消了,超时任务不会被执行。在这里插入图片描述

startQueryTimer方法中的timeout参数是sql执行超时时间,PropertyKey.enableQueryTimeouts属性默认值是true。因此只要sql执行超时不为空,就会创建一个CancelQueryTaskImpl任务,并且这个任务会在到达sql执行超时的时间线被执行(session.getCancelTimer().schedule(timeoutTask, timeout)延迟调度任务)在这里插入图片描述
我们再往下看看这个CancelQueryTaskImpl任务是如何运行的。从下面的代码可以看出,CancelQueryTaskImpl.run方法首先启动了一个线程,然后在这个线程中执行sql脚本KILL QUERY {query_threadId}去杀掉这个查询线程。***注意:***这里是每次sql执行都会启动一个新线程,没有使用线程池(应该是为了保证超时任务能得到及时的调度,线程池中的线程数是有限的,任务数过多就会放在任务队列中,任务调度不可避免有一定延迟),在高并发的情况下会创建大量的线程,可能导致系统资源占用过高,甚至导致jvm虚拟机崩溃退出,所以在高并发环境中不建议使用sql执行超时这个功能。

在这里插入图片描述

5. transactionTimeout 和 innodb_lock_wait_timeout

transactionTimeout :spring事务注解@Transactional的超时时间,上面说到了,这个值将会作为sql执行超时,可以说它是客户端的事务超时参数。
innodb_lock_wait_timeout: mysql server的环境变量,用于设置事务在等待获取锁时的超时时间。当一个事务请求锁资源时,如果该资源已经被其他事务锁定,那么该事务就会进入等待状态。如果一个事务等待获取锁的时间超过了该设置的时间,MySQL 将会自动中断该事务。因此这个参数可以说它是服务端的事务超时参数。

6. netTimeoutForStreamingResults

netTimeoutForStreamingResults:主要用来在处理流式结果集时mysql server返回大量数据的超时时间,防止等待结果集的时间过长。
在这里插入图片描述
setupStreamingTimeout 根据流结果超时时间(PropertyKey.netTimeoutForStreamingResults的默认值是600)和是否需要流结果集方法createStreamingResultSet 来综合判断是否需要向服务端发送net_write_timeout属性。
在这里插入图片描述

  protected boolean createStreamingResultSet() {
        return ((this.query.getResultType() == Type.FORWARD_ONLY) && (this.resultSetConcurrency == java.sql.ResultSet.CONCUR_READ_ONLY)
        //getResultFetchSize默认值是0
                && (this.query.getResultFetchSize() == Integer.MIN_VALUE));
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/674716.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

U盘感染病毒,不必急于扔掉!教你如何有效清除U盘中的病毒

U盘被感染了只能扔掉吗&#xff1f;随着信息时代的飞速发展&#xff0c;U盘已成为我们日常生活中不可或缺的存储设备。然而&#xff0c;在使用U盘的过程中&#xff0c;我们有时会遇到U盘被病毒感染的情况。面对这一问题&#xff0c;许多人可能会感到恐慌&#xff0c;甚至想要直…

Ubuntu22.04之解决:terminal使用alt+1/alt+2/alt+3失效问题(二百三十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

UML实现图-组件图

概述 组件图(ComponentDiagram)描述了软件的各种组件和它们之间的依赖关系。组件图中通常包含4种元素:组件、程序、包、任务&#xff0c;各个组件之间还可以相互依赖。 一、组件的表示法 组件是定义了良好接口的物理实现单元&#xff0c;是系统中可替换的物理部件。在一般情…

动物群体甲基化如何讲故事?

DNA甲基化是DNA化学修饰的一种形式&#xff0c;能够在不改变DNA序列的前提下&#xff0c;改变基因表达&#xff0c;从而使表型发生变化。DNA甲基化是一种非常保守的表观遗传修饰&#xff0c;其广泛存在于生物体内&#xff0c;在不同的物种间、相同物种不同环境&#xff0c;同一…

学完PMP,怎么应用到实际工作中?

学习理论知识只是第一步&#xff0c;其目的是为了在实际工作中能够提供帮助。我相信题主的问题也是许多人共同面临的。PMP的知识体系是专业项目管理所必须掌握的知识体系。俗话说&#xff0c;有备无患&#xff0c;具备专业的理论知识就是最好的准备。废话不多说&#xff0c;举几…

使用 zxing 生成二维码以及条形码

需求背景 前期在做项目的时候&#xff0c;有一个需求是说要生成一张条形码&#xff0c;并且呢将条形码插入到 excel 中去&#xff0c;但是之前一直没有搞过找个条形码或者是二维码&#xff0c;最后是做出来了&#xff0c;这里呢就先看看怎么生成&#xff0c;后面再抽时间来写写…

6.3 cf 944

Problem - C - Codeforces 思路 分四种情况&#xff0c;以12为分界点 &#xff08;紫色部分是最初思路&#xff0c;但不包含所有情况&#xff09; 只看在a<b c<d 时的图 代码 #include <bits/stdc.h> using namespace std; #define IOS ios::sync_with_stdio(…

web前端三大主流框架指的是什么

web前端三大主流框架是什么&#xff1f;前端开发师的岗位职责有哪些&#xff1f;这边整理了相关内容供大家参考了解&#xff0c;请各位小伙伴随小编一起查阅下面的内容。 web前端三大主流框架 web前端三大主流框架是Angular、React、Vue。 1.Angular Angular原名angularJS诞生…

OJ3376无尽的石头问题

答案&#xff1a; #include<bits/stdc.h> using namespace std; const int N10e7; int fx(int n) {int sum0;while(n){sum(n%10);n/10;}return sum; } int main() {int t,n,x;cin>>t;while(t--){cin>>n;int count0;for(int i1;i<N;){if(in){cout<<…

网关(Gateway)- 自定义过滤器工厂

自定义过滤工厂类 DemoGatewayFilterFactory package com.learning.springcloud.custom;import org.apache.commons.lang.StringUtils; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GatewayFilterChai…

FreeRTOS【16】直达任务通知使用

1.开发背景 直达任务通知&#xff0c;FreeRTOS 的线程任务提供的接口&#xff0c;可以用作线程唤醒&#xff0c;或者是传递数据&#xff0c;因为是基于线程本身的操作&#xff0c;是轻量级&#xff0c;速度响应更快&#xff0c;适合小内存芯片使用。 事实上本人使用得比较少&am…

pytorch笔记:自动混合精度(AMP)

1 理论部分 1.1 FP16 VS FP32 FP32具有八个指数位和23个小数位&#xff0c;而FP16具有五个指数位和十个小数位Tensor内核支持混合精度数学&#xff0c;即输入为半精度&#xff08;FP16&#xff09;&#xff0c;输出为全精度&#xff08;FP32&#xff09; 1.1.1 使用FP16的优缺…

大渡口数字经济产业商会暨尼伽OLED透明屏产品发布会

2024年5月31日&#xff0c;大渡口数字经济产业商会成功举办了一场盛大的“商会数字经济发展项目签约大会”&#xff0c;活动上不仅深入探讨了构建“义渡新质生产力”及如何更好地“建功重庆西部大开发”的战略议题&#xff0c;还正式与尼伽OLED宣布达成战略合作伙伴关系&#x…

Java版工程项目管理系统源码:技术框架与功能实现全解析

在工程行业&#xff0c;项目管理的高效协同和信息共享是提升管理效率和精度的关键。本文将详细介绍一款采用先进技术框架的Java版工程项目管理系统&#xff0c;该系统支持前后端分离&#xff0c;功能全面&#xff0c;可满足不同角色的需求。从项目进度图表到施工地图&#xff0…

10个从基础到高级的GPT提示词优化指南

为一名大模型的深度用户和微软Copilot的首批开放测试者&#xff0c;很多人会问我如何写出高效的提示词。同时&#xff0c;也有不少读者反映&#xff0c;像ChatGPT和Claude这样的模型并没有想象中那么神奇&#xff0c;无法满足他们的实际需求。 首先我想说&#xff0c;确实像Ch…

双指针_复写零

复写零 题目描述&#xff1a; 题目链接&#xff1a;复写零 内容&#xff1a; 这道题目要求我们每遇到一次0就复写一遍&#xff0c;并且只能在原数组上进行修改&#xff0c;不能越界访问。 算法原理&#xff1a; 思路1&#xff1a; 如果我们用两个指针cur,dest同时从指向第一个…

c# 输出二进制字符串

参考链接 C#二进制输出数据_c# 输出二进制 123.5的方法-CSDN博客https://blog.csdn.net/a497785609/article/details/4572112标准数字格式字符串 - .NET | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings#BFo…

工业HMI设计,稳定压倒一切,那高颜值就不稳定了吗?

提及工业HMI设计&#xff0c;很多小伙伴就跳出来说&#xff0c;工业 HMI稳定是最重要的&#xff0c;颜值没比必要&#xff0c;花里呼哨的.我承认稳定的重要性&#xff0c;但是稳定与颜值并不是一对矛盾体。本文就分享为什么工业HMI稳定性重要&#xff1f;为什么高颜值也重要&am…

QT:QML中使用Loader加载界面

目录 一.介绍 二.实现 三.效果展示 四.代码 一.介绍 在QML中使用Loader加载界面&#xff0c;可以带来诸多好处&#xff0c;如提高应用程序的启动速度、动态地改变界面内容、根据条件加载不同的组件、更有效地使用内存以及帮助分割应用逻辑等。 1.延迟加载&#xff1a;QML…

动态规划2:面试题 08.01. 三步问题

动态规划解题步骤&#xff1a; 1.确定状态表示&#xff1a;dp[i]是什么 2.确定状态转移方程&#xff1a;dp[i]等于什么 3.初始化&#xff1a;确保状态转移方程不越界 4.确定填表顺序&#xff1a;根据状态转移方程即可确定填表顺序 5.确定返回值 题目链接&#xff1a;面试…