如何防止“表X被READ锁锁定并且无法更新”?

时间:2019-07-17 06:31:18

标签: mysql

我正在使用带有日期范围的MySQL表。这些日期范围可能会重叠,例如G。日期范围从2019-01-012019-01-10,第二个日期范围从2019-01-052019-01-15。我需要一个组合的日期范围来进行时间计算,在示例中,范围是2019-01-012019-01-15。我编写了一个过程,用合并的结果创建一个临时表。

某些函数使用此临时表进行一些时间计算。这些函数调用该过程以创建临时表(如果不存在)。但是,如果临时表已经存在,则会出现错误“表已被READ锁锁定,无法更新”。如果在调用创建过程之前删除了临时表,则不会收到错误消息。但是,每次必须重新创建临时表时,查询将花费几乎一秒钟的时间来完成。

如何在不每次都删除临时表的情况下防止错误发生?

示例:

drop database if exists TempTestDB;
create database TempTestDB;
USE `TempTestDB`;

create table TestTable(
test int auto_increment not null primary key,
name varchar(45))
;

-- real table has time data
INSERT INTO TestTable (`name`) VALUES ('test1');

DROP procedure IF EXISTS `createTempTestTable`;

DELIMITER $$
USE `TempTestDB`$$
CREATE DEFINER=`riedel`@`%` PROCEDURE `createTempTestTable`()
BEGIN

-- the temp table contains merged rows of the base table
CREATE TEMPORARY TABLE IF NOT EXISTS TempTestTable select * from TestTable;

INSERT INTO TempTestTable (`name`) VALUES ('test2');

END$$

DELIMITER ;

USE `TempTestDB`;

DELIMITER $$
USE `TempTestDB`$$
CREATE FUNCTION `getTimeForUser`(user int) RETURNS INT
BEGIN

-- real function does some time calculation

declare result int;

call TempTestDB.createTempTestTable;

select count(*) from TempTestTable into result;

RETURN result;

END$$

DELIMITER ;

select TempTestDB.getTimeForUser(1) union select TempTestDB.getTimeForUser(2);drop database if exists TempTestDB;
create database TempTestDB;
USE `TempTestDB`;

create table TestTable(
test int auto_increment not null primary key,
name varchar(45))
;

-- real table has time data
INSERT INTO TestTable (`name`) VALUES ('test1');

DROP procedure IF EXISTS `createTempTestTable`;

DELIMITER $$
USE `TempTestDB`$$
CREATE DEFINER=`riedel`@`%` PROCEDURE `createTempTestTable`()
BEGIN

-- the temp table contains merged rows of the base table
CREATE TEMPORARY TABLE IF NOT EXISTS TempTestTable select * from TestTable;

INSERT INTO TempTestTable (`name`) VALUES ('test2');

END$$

DELIMITER ;

USE `TempTestDB`;

DELIMITER $$
USE `TempTestDB`$$
CREATE FUNCTION `getTimeForUser`(user int) RETURNS INT
BEGIN

-- real function does some time calculation

declare result int;

call TempTestDB.createTempTestTable;

select count(*) from TempTestTable into result;

RETURN result;

END$$

DELIMITER ;

select TempTestDB.getTimeForUser(1) union select TempTestDB.getTimeForUser(2);

0 个答案:

没有答案