日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 类似oracle,mysql – 制作类似于Oracle的seqences的机制

發(fā)布時(shí)間:2025/3/20 数据库 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 类似oracle,mysql – 制作类似于Oracle的seqences的机制 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。