`
xjywp2008
  • 浏览: 7737 次
文章分类
社区版块
存档分类
最新评论

MYSQL 函数调用导致自动生成共享锁问题

阅读更多
MySQL版本:5.6.27
导致问题出现的MYSQL配置:my.ini中配置了log-bin=mysql-bin
问题重现配置:
表:
CREATE TABLE `t_oss_uniqueid` (
  	`name` varchar(50) NOT NULL DEFAULT '' COMMENT '表名(大写)',
  	`current_value` bigint(11) DEFAULT NULL COMMENT 'value',
  	`PREFIX` bigint(11) DEFAULT NULL COMMENT '前缀',
  	PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='ID资源表';

函数:
#简称fun1 –只作为描述语
CREATE FUNCTION `f_oss_getuniqueid`( seq_Name VARCHAR(50),seq_step INT(11)) RETURNS varchar(50) CHARSET utf8
      DETERMINISTIC
BEGIN
      DECLARE THE_PREFIX INTEGER; 
SELECT PREFIX INTO THE_PREFIX FROM t_oss_uniqueid  WHERE NAME = seq_Name;   
RETURN 
CONCAT(THE_PREFIX,DATE_FORMAT(SYSDATE(),"%Y%m%d"),LPAD(f_oss_nextuniqueid(seq_Name,seq_step),8,0));
END;

#简称fun2 –只作为描述语
CREATE FUNCTION `f_oss_nextuniqueid`(seq_name VARCHAR(50), seq_step INT(11)) RETURNS int(11)
    DETERMINISTIC
BEGIN
DECLARE THE_VALUE INTEGER;
	SET THE_VALUE = 0;  
      UPDATE t_oss_uniqueid  SET current_value = current_value + seq_step WHERE NAME = seq_name;
      SELECT current_value INTO THE_VALUE FROM t_oss_uniqueid  WHERE NAME = seq_name;   
      IF  THE_VALUE<100000000 THEN 
       	RETURN THE_VALUE;
      ELSE 
       	update t_oss_uniqueid set current_value=1   WHERE NAME = seq_name;                    
      		RETURN 1;
      END IF;
END;



场景简介:
前提:mysql配置log-bin=mysql-bin;
场景1:
  • 1. 不修改fun1与fun2。
  • 2. 调用fun1函数。
  • 3. fun1函数内部的select语句会出现自动加上S锁。
  • 4. fun2函数内部update自动获取X锁。
  • 5. 多线程并发,会导致死锁。

场景2:
  • 1. 修改fun1,select语句加上for update。Fun2 不修改。
  • 2. 调用fun1函数。
  • 3. fun1函数内部的select语句会出现自动获取X锁
  • 4. fun2函数内部update自动获取X锁。
  • 5. 多线程并发,不会出现死锁。


场景3:
  • 1. 修改fun1,fun2。合并成一个函数为fun1。
  • 2. 调用fun1函数。
  • 3. fun1函数内部只会出现X锁,无S锁出现。
  • 4. 多线程并发,不会出现死锁。


场景4:
  • 1. 不修改fun1。修改fun2,注释掉第一个update语句。
  • 2. 调用fun1函数。
  • 3. fun1函数内部的select语句会自动加上S锁。
  • 4. fun2函数内部不会出现X锁。
  • 5. 多线程并发,不会出现死锁,但是功能已经不完整。


场景5:
  • 1. 不修改fun1。修改fun2,注释掉两个update语句。
  • 2. 调用fun1函数。
  • 3. fun1函数内部无锁。
  • 4. fun2函数内部无锁。
  • 5. 多线程并发,不会出现死锁,但是功能已经不完整。

分享到:
评论
3 楼 lamberkun 2016-08-16  
楼主辛苦了,干货,mark。
2 楼 suqianxue 2016-08-01  
    
1 楼 cahdj123 2016-08-01  
楼主辛苦了,干货,mark。

相关推荐

    mysql使用中需要注意事项

    如果数据库连接出现了问题,需要重置连接,此时应该重新建立连接,并且重新调用与MySQL连接相关的函数,如mysql_stmt_init。为了检查数据库连接是否有效,可以使用mysql_ping函数。MySQL连接有两种实现方式:一种是...

    MySQL++使用手册

    - **目的**:解决由于嵌入式 MySQL C API 导致的编译问题。 - **代码**:例如,排除不必要的头文件。 **8.4 在缺少完整 C99 支持的系统上构建 MySQL++** - **目的**:提供在没有完整 C99 支持的系统上构建 MySQL++ ...

    2020-review-8-mysql.pptx

    4. **减少函数调用**:函数调用可能会影响查询性能,尤其是当这些函数作用于索引列时。 5. **使用EXPLAIN分析SQL执行计划**:通过EXPLAIN命令查看SQL语句的执行计划,帮助识别潜在的性能瓶颈。 #### 五、总结 ...

    Mysql8.0 Window 动态链接库

    动态链接库(DLL)是一种共享库,它包含了一系列可执行代码和数据,多个程序可以同时调用这些功能,以节省内存并促进代码重用。在MySQL 8.0中,动态链接库扮演着关键角色,提供了核心服务、数据库引擎以及与应用程序...

    MySQl数据库应用2022版

    6. **事务处理与并发控制**:理解事务的概念,学习如何使用BEGIN、COMMIT、ROLLBACK语句进行事务管理,并探讨锁机制(共享锁、排他锁)在多用户并发环境下的作用。 7. **备份与恢复**:学习如何备份数据库,以及在...

    mysql面试题.zipmysql面试题.zip

    - 锁机制:共享锁(读锁)、排他锁(写锁)、行级锁、表级锁、页级锁等。 - InnoDB的MVCC(多版本并发控制):实现高并发读写。 10. 数据库优化: - 查询优化:避免全表扫描,合理使用索引,减少JOIN操作。 - ...

    MySQL中文参考手册.rar

    6. **事务处理与并发控制**:介绍MySQL中的事务特性,包括ACID属性,以及锁机制,如共享锁、排他锁和行级锁定。 7. **备份与恢复**:讲解如何进行数据库的完整备份、增量备份,以及如何在数据丢失或损坏时恢复数据...

    MySQL++ v3.1.0教程

    开发者可以通过构造 `Connection` 实例并调用其成员函数来执行数据库操作。 ##### 2.2 Query 对象 `Query` 对象用于构建 SQL 语句。它可以被看作是一个灵活的容器,允许开发者动态构建复杂的查询语句。通过将 SQL ...

    MySQL数据库对并发事件的控制和处理.pdf

    在实际应用中,可以通过ODBC(Open Database Connectivity)API或MySQL自带的C API函数来调用MySQL数据库的功能,实现对并发事件的控制和处理。ODBC提供了一个统一的接口,使得不同数据库系统之间的交互变得更加简单...

    Mysql面试题.zip

    3. 并发控制:理解锁定机制,如共享锁(读锁)和独占锁(写锁),以及死锁的概念和解决方法。 四、视图与存储过程 1. 视图:理解视图的作用,如何创建、修改和删除视图,以及视图在查询优化中的应用。 2. 存储过程...

    mysql的启动过程详解

    对于并发操作,MySQL使用行级锁定来减少冲突,并支持多种锁定模式,如共享锁(读锁)和独占锁(写锁)。 最后,当服务器接收到关闭命令或者达到预设的停止条件时,MySQL会进入关闭流程,清理资源,关闭打开的文件,...

    Python的互斥锁与信号量详解

    值得注意的是,获取锁之后必须释放锁,否则会导致死锁问题,即线程永久性等待锁的释放。 在描述中提到的Rlock,实际上应该指的是Reentrant Lock(可重入锁),它允许同一个线程在未释放其持有的锁的情况下多次获得...

    php分卷备份还原mysql数据库.pdf

    `db()`构造函数用于建立到MySQL服务器的连接,通过`mysql_connect()`函数。参数分别为服务器地址、用户名、密码和数据库名。如果连接失败,会通过`die()`函数输出错误信息。 2. **数据库选择**: 使用`mysql_...

    百度校园招聘历年经典面试题汇总:C++研发 1

    32. **堆与栈**:堆是动态内存分配区域,栈是函数调用时分配的内存,自动管理。 33. **new与malloc**:new是C++关键字,负责对象的构造;malloc是C语言的内存分配函数,不调用构造函数。 34. **析构函数异常要求**...

    C++连接使用MySQL的方法

    1. **MySQL C API**: MySQL提供了一个C语言接口,使得C++程序能够直接调用这些函数来完成与MySQL服务器的通信。在C++中,我们可以使用结构体`MYSQL`来代表一个数据库连接。 2. **初始化和配置**: 在C++类`MySQLCon`...

    API控制外部组件例程

    在IT行业中,API(应用程序接口)是软件系统之间交互的核心工具,它允许不同的应用程序通过预定义的函数调用来实现功能的共享和数据的交换。"API控制外部组件例程"这个主题聚焦于如何通过API来管理和操作外部组件,...

    面试题,涵盖golong、mysql、redis、MongoDB、RabbitMQ、Kafka、Docker等等

    启动一个 Goroutine 非常简单,只需要在函数调用前加上关键字 `go`。例如,`go myFunc()`。为了确保 Goroutine 正确结束,通常需要结合 Channel 来控制 Goroutine 的生命周期。Goroutine 可以通过 Channel 通信,...

    Michelle F的程序媛之路(Mysql篇)

    - **共享锁(S Lock)**:允许多个用户读取一行数据。 - **排他锁(X Lock)**:只允许获取锁的用户写入数据。 - **意向锁**:表示对表或数据库的锁定意图。 #### 九、 视图 **知识点:** 视图是虚拟表,基于一个...

    第九章课后习题1

    9. **锁的类型与粒度**:MySQL的锁有共享锁(Shared Locks),粒度可以是行级(InnoDB存储引擎)或表级(如MyISAM)。共享锁也被称为读锁,允许多个事务同时读取同一数据,但不允许写入。 10. **事务隔离级别**:...

Global site tag (gtag.js) - Google Analytics