mysql 类似oracle,mysql – 制作类似于Oracle的seqences的机制
MySQL提供了一種增加記錄ID的自動機制.這可以用于許多目的,但我需要能夠使用ORACLE提供的序列.顯然,為此目的創建表是沒有意義的.
解決方案應該很簡單:
1)創建一個表來托管所有需要的序列,
2)創建一個增加特定序列值并返回新值的函數,
3)創建一個返回序列當前值的函數.
從理論上講,它看起來很簡單……但……
增加序列的值(與Oracle中的nextval非常相似)時,需要阻止其他會話執行此操作(甚至獲取當前值),直到更新完成.
兩個理論選擇:
a – 使用UPDATE語句,該語句將在單個鏡頭中返回新值,或者
b – 在UPDATE和SELECT之間鎖定表.
不幸的是,似乎MySQL不允許在函數/過程中鎖定表,并且在嘗試在單個語句中完成整個操作(如UPDATE … RETURNING …)時,必須使用@ -type變量才能生存完成功能/程序.
有沒有人有這個想法/工作解決方案?
謝謝.
解決方法:
以下是FOR UPDATE intention lock的簡單示例.使用INNODB引擎的行級鎖定.該示例顯示了下一個可用序列的四行,這些序列不會受到眾所周知的INNODB Gap Anomaly的影響(在使用AUTO_INCREMENT失敗后出現間隙的情況).
架構:
-- 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或臃腫的代碼,這會延遲Lock Wait上的其他客戶端.意思是,盡快使用下一個序列,執行更新(遞增部分)和COMMIT.
以上在存儲過程中:
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 ;
測試:
set @myNum:= -1;
call getNextSequence('Carburetor',@myNum);
+------------+
| yourSeqNum |
+------------+
| 4 |
+------------+
select @myNum; -- 4
根據需要相應地修改存儲過程,例如只有2個機制中的一個用于檢索序列號(OUT參數或結果集).換句話說,很容易拋棄OUT參數概念.
如果您不遵守ASOCK的ASAP版本(更新后顯然不需要),并且在發布之前繼續執行耗時的代碼,則在等待序列的其他客戶端的超時期限之后可能會發生以下情況數:
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting
transaction
希望這絕不是一個問題.
show variables where variable_name='innodb_lock_wait_timeout';
在我的系統上,它的值為50(秒).在大多數情況下,等待一兩秒以上可能是無法忍受的.
在TRANSACTIONS期間也感興趣的是以下命令的輸出部分:
SHOW ENGINE INNODB STATUS;
標簽:sequences,mysql
來源: https://codeday.me/bug/20190916/1807447.html
總結
以上是生活随笔為你收集整理的mysql 类似oracle,mysql – 制作类似于Oracle的seqences的机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab中的图像,MATLAB中图像
- 下一篇: php 操作权限,liunx下PHP操作