[英]Oracle sequences equivalent in MySQL
I have following table similar to Oracle user_sequences
. 我有类似于Oracle
user_sequences
下表。
I have logic of sequence prefix/suffix something, but for simplicity, I'm skipping as matters less here. 我有序列前缀/后缀的逻辑,但是为了简单起见,在这里我略过了一些事。
create table my_seq(
min_value integer,
Max_value integer,
last_value integer,
increment_by tinyint,
customer_id integer);
Assume in current table there are two records. 假设在当前表中有两条记录。
insert into my_seq(min_value,max_value,last_value,increment_by,customer_id)
values(1,99999999,1,1,'foo#',1),(1,999999999,100,1,'foo#',2);
My foo table structure is like, 我的foo表结构就像
create table foo(id Auto_increment,foo_number varchar(20),customer_id integer)
; create table foo(id Auto_increment,foo_number varchar(20),customer_id integer)
;
Constrained: I can't use MySQL AUTO_INCREMENT columns as foo
contains different customers data, and every customer could opt foo_number
auto generation or manual entry and there should be gap if customer opted for auto_generation. 约束:我不能使用MySQL AUTO_INCREMENT列,因为
foo
包含不同的客户数据,并且每个客户都可以选择foo_number
自动生成或手动输入,并且如果客户选择了auto_generation,则应该有空白。 So customer=1 has opted for it, foo# should be 1,2,3,4 etc, no gaps are allowed. 因此,customer = 1选择了它,foo#应该是1,2,3,4,依此类推,不允许有空格。
So far so good, with auto increment logic that we have implemented if my app runs in single thread
. 到目前为止,如果我的应用程序在
single thread
运行,我们已经实现了自动递增逻辑。 We generate foo_number
and populate in foo
table, along with other data points. 我们生成
foo_number
并与其他数据点一起填充到foo
表中。
I simply do a query to get the next auto#. 我只是简单地查询以获取下一个auto#。
select last_number from my_seq where customer_id=?;
reads the # and the update the record. 读取#并更新记录。
update my_seq set last_number=last_number+increment_by where customer_id=?;
Problem: When multiple concurrent session tries the run select last_number from my_seq...
, it returns same foo_number
multiple times. 问题:当多个并发会话尝试运行
select last_number from my_seq...
,它将多次返回相同的foo_number
。 Also, I can't enforce single thread in application because of application side limitation and performance bottleneck, hence need to solve it in database side. 另外,由于应用程序端的限制和性能瓶颈,我无法在应用程序中强制执行单线程,因此需要在数据库端解决它。
Please suggest, how I could avoid duplicate numbers? 请提出建议,如何避免重复的数字? Please help, thanks in advance.
请帮助,在此先感谢。
I did google, many stackoverflow links suggests get_last_id()
, as you could see, I can't use it. 我做了谷歌,许多stackoverflow链接建议
get_last_id()
,如您所见,我不能使用它。
I was able to solve this problem by just combining suggestions of @Akina and @RickJames , thank you both for thier support. 我可以通过组合@Akina和@RickJames的建议来解决此问题,谢谢你们俩的支持。
create table my_seq(
min_value integer,
Max_value integer,
last_value integer,
increment_by tinyint,
customer_id integer)ENGINE = InnoDB;
Here ENGINE=InnoDB
is very important. 在这里
ENGINE=InnoDB
非常重要。 In order to make sure there is table level locking while reading, I have modified my app code to: 为了确保在读取时有表级锁定,我将应用程序代码修改为:
Auto-Commit=FALSE
Then, 然后,
//very import to begin the transaction
begin;
select last_number from my_seq where customer_id=? FOR UPDATE;
Read the result in App.
update my_seq set last_number=last_number+1 where customer_id=?;
commit;
This was generating the unique sequence number
even in case of multiple concurrent sessions. 即使在多个并发会话的情况下,这也会生成唯一的
sequence number
。
I have faced another problem, that this solution has slowed down other are where I do generate sequence#. 我遇到了另一个问题,该解决方案减慢了其他我生成序列号的地方。 I have solved it enabling a row level lock instead of table level lock by indexing customer_id.
我已经解决了通过索引customer_id启用行级锁而不是表级锁的问题。
ALTER TABLE TABLE_NAME ADD INDEX (customer_id);
Hope this will be help full to others. 希望这对其他人有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.