暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL 客户端之 mysql_reset_connection

上下博客 2021-04-21
5165
今天在读MySQL相关文章的时候说到MySQL5.7版本增加了一条客户端函数:mysql_reset_connection
与连接有关的状态受到以下影响

回滚所有活动的事务,并重置自动提交模式。


所有 table 锁均已释放。


所有TEMPORARYtable 均已关闭(并删除)。


会话系统变量将重新初始化


用户变量设置丢失。


准备好的语句被释放。


HANDLER关闭。


LAST_INSERT_ID 为 0


用 GET_LOCK 释放。

抱着“知其然知其所以然”的学习态度查看了一下相关的代码,这里参考的为:mysql-5.7.33

    int STDCALL
    mysql_reset_connection(MYSQL *mysql)
    {
    /**
    * 根据_dbug_on_状态判断是否需要调试
    * 如果需要调试会调用_db_enter_进行
    * 调试相关的CODE_STATE堆栈设置
    */
    DBUG_ENTER("mysql_reset_connection");




    /**
    * mysql指向st_mysql_methods结构体别名:methods,
    * mysql->methods = &client_methods; client_methods指向client_methods结构
    * 所以advanced_command是指向cli_advanced_command的指针
    * 调用net_write_command函数将mysql_reset_connection命令发送给server
    * 由于skip_check为 0 所以不调用cli_safe_read_with_ok函数取读取返回的包
    * 如果失败则直接返回非 0 值,mysql_reset_connection函数结束。
    */
    if (simple_command(mysql, COM_RESET_CONNECTION, 0, 0, 0))
    DBUG_RETURN(1);
    else
    {
    /**
    * 清除每个语句的连接指针,如果尝试使用已经关闭的语句指针非常有必要
    * 解释见下块代码
    */
    mysql_detach_stmt_list(&mysql->stmts, "mysql_reset_connection");
    /* 重置一些mysql的成员信息 */
    mysql->insert_id = 0; /** LAST_INSERT_ID 置为 0 */
    mysql->affected_rows = ~(my_ulonglong)0; /** 释放受影响的行数,这里进行了一个反码操作 */
    /**
    * 释放旧的结果集并且初始化 field_alloc
    * 这里会假定一个长度 8192
    */
    free_old_query(mysql);
    mysql->status = MYSQL_STATUS_READY;/** 设置为准备状态 */
    DBUG_RETURN(0);
    }
    }
      void mysql_detach_stmt_list(LIST **stmt_list MY_ATTRIBUTE((unused)),
      const char *func_name MY_ATTRIBUTE((unused))) {
      #ifdef MYSQL_CLIENT
      LIST *element = *stmt_list;
      char buff[MYSQL_ERRMSG_SIZE];
      DBUG_ENTER("mysql_detach_stmt_list");
      /** 将调用这个函数的函数名称存放到 buff 里 */
      my_snprintf(buff, sizeof(buff) - 1, ER(CR_STMT_CLOSED), func_name);
      for (; element; element = element->next) {
      MYSQL_STMT *stmt = (MYSQL_STMT *)element->data;
      /** 设置每个预处理的错误信息 */
      set_stmt_error(stmt, CR_STMT_CLOSED, unknown_sqlstate, buff);
      /** 将预处理对象的mysql对象置为空 */
      stmt->mysql = 0;
      /* 这里的语句不需要调用 list_delete */
      }
      /** 将整个lsit置空 */
      *stmt_list = 0;
      DBUG_VOID_RETURN;
      #endif /* MYSQL_CLIENT */
      }
      可以发现命令基本上将句柄都给置空,并且清理掉了预处理语句、结果集。代码里我基本上每行都注释了一下,愿常看常新,个人理解,如有错误还望指出。


      文章转载自上下博客,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论