mysql 类似oracle,mysql – 制作类似于Oracle的seqences的机制
MySQL提供了一種增加記錄ID的自動(dòng)機(jī)制.這可以用于許多目的,但我需要能夠使用ORACLE提供的序列.顯然,為此目的創(chuàng)建表是沒有意義的.
解決方案應(yīng)該很簡(jiǎn)單:
1)創(chuàng)建一個(gè)表來托管所有需要的序列,
2)創(chuàng)建一個(gè)增加特定序列值并返回新值的函數(shù),
3)創(chuàng)建一個(gè)返回序列當(dāng)前值的函數(shù).
從理論上講,它看起來很簡(jiǎn)單……但……
增加序列的值(與Oracle中的nextval非常相似)時(shí),需要阻止其他會(huì)話執(zhí)行此操作(甚至獲取當(dāng)前值),直到更新完成.
兩個(gè)理論選擇:
a – 使用UPDATE語句,該語句將在單個(gè)鏡頭中返回新值,或者
b – 在UPDATE和SELECT之間鎖定表.
不幸的是,似乎MySQL不允許在函數(shù)/過程中鎖定表,并且在嘗試在單個(gè)語句中完成整個(gè)操作(如UPDATE … RETURNING …)時(shí),必須使用@ -type變量才能生存完成功能/程序.
有沒有人有這個(gè)想法/工作解決方案?
謝謝.
解決方法:
以下是FOR UPDATE intention lock的簡(jiǎn)單示例.使用INNODB引擎的行級(jí)鎖定.該示例顯示了下一個(gè)可用序列的四行,這些序列不會(huì)受到眾所周知的INNODB Gap Anomaly的影響(在使用AUTO_INCREMENT失敗后出現(xiàn)間隙的情況).
架構(gòu):
-- drop table if exists sequences;
create table sequences
( id int auto_increment primary key,
sectionType varchar(200) not null,
nextSequence int not null,
unique key(sectionType)
) ENGINE=InnoDB;
-- truncate table sequences;
insert sequences (sectionType,nextSequence) values
('Chassis',1),('Engine Block',1),('Brakes',1),('Carburetor',1);
示例代碼:
START TRANSACTION; -- Line1
SELECT nextSequence into @mine_to_use from sequences where sectionType='Carburetor' FOR UPDATE; -- Line2
select @mine_to_use; -- Line3
UPDATE sequences set nextSequence=nextSequence+1 where sectionType='Carburetor'; -- Line4
COMMIT; -- Line5
理想情況下,您根本沒有Line3或臃腫的代碼,這會(huì)延遲Lock Wait上的其他客戶端.意思是,盡快使用下一個(gè)序列,執(zhí)行更新(遞增部分)和COMMIT.
以上在存儲(chǔ)過程中:
DROP PROCEDURE if exists getNextSequence;
DELIMITER $$
CREATE PROCEDURE getNextSequence(p_sectionType varchar(200),OUT p_YoursToUse int)
BEGIN
-- for flexibility, return the sequence number as both an OUT parameter and a single row resultset
START TRANSACTION;
SELECT nextSequence into @mine_to_use from sequences where sectionType=p_sectionType FOR UPDATE;
UPDATE sequences set nextSequence=nextSequence+1 where sectionType=p_sectionType;
COMMIT; -- get it and release INTENTION LOCK ASAP
set p_YoursToUse=@mine_to_use; -- set the OUT parameter
select @mine_to_use as yourSeqNum; -- also return as a 1 column, 1 row resultset
END$$
DELIMITER ;
測(cè)試:
set @myNum:= -1;
call getNextSequence('Carburetor',@myNum);
+------------+
| yourSeqNum |
+------------+
| 4 |
+------------+
select @myNum; -- 4
根據(jù)需要相應(yīng)地修改存儲(chǔ)過程,例如只有2個(gè)機(jī)制中的一個(gè)用于檢索序列號(hào)(OUT參數(shù)或結(jié)果集).換句話說,很容易拋棄OUT參數(shù)概念.
如果您不遵守ASOCK的ASAP版本(更新后顯然不需要),并且在發(fā)布之前繼續(xù)執(zhí)行耗時(shí)的代碼,則在等待序列的其他客戶端的超時(shí)期限之后可能會(huì)發(fā)生以下情況數(shù):
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting
transaction
希望這絕不是一個(gè)問題.
show variables where variable_name='innodb_lock_wait_timeout';
在我的系統(tǒng)上,它的值為50(秒).在大多數(shù)情況下,等待一兩秒以上可能是無法忍受的.
在TRANSACTIONS期間也感興趣的是以下命令的輸出部分:
SHOW ENGINE INNODB STATUS;
標(biāo)簽:sequences,mysql
來源: https://codeday.me/bug/20190916/1807447.html
總結(jié)
以上是生活随笔為你收集整理的mysql 类似oracle,mysql – 制作类似于Oracle的seqences的机制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab中的图像,MATLAB中图像
- 下一篇: 将mysql的数据库导入到linux_l