Reputation: 33
In my MariaDB I have two tables project
and issue
, the issue
table contains all issues created for all projects
create table if not exists Project(
id integer PRIMARY KEY auto_increment,
`name` varchar(200) NOT NULL
);
create table if not exists Issue(
id integer PRIMARY KEY AUTO_INCREMENT,
project_id integer,
issue_number integer,
content text,
FOREIGN KEY (project_id)
REFERENCES Project(id)
);
The issue_number
is per project and starts always from 1, how can increment it by 1 and resolve concurrent insert problems?
I can't use select max(issue_number) + 1 from Issue where project_id=X
to determine the new value because could be stale
Upvotes: 1
Views: 114
Reputation: 48865
You can create a "sequencing" table to store the next issue number for each project.
create table sequencing (
project_id int primary key not null,
next_number int
);
insert into sequencing (project_id, next_number) values (1234, 1);
You can use Optimistic Locking or Pessismistic Locking to resolve the race condition. The sequence below uses Pessimistic Locking. The Optimistic Locking solution is slightly different (not shown here).
When inserting a new issue, you will do:
In SQL this will look like:
start transaction;
select next_number -- save this number in app as "n"
from sequencing
where project_id = 1234
for update;
update sequencing
set next_number = next_number + 1
where project_id = 1234;
insert into issue (..., issue_number) values (..., n); -- use "n" here
commit;
Upvotes: 1
Reputation: 14958
You could calculate the field issue_number
, there is no need to store it:
SELECT
id,
project_id,
row_number() over (partition by project_id order by id) as issue_number,
content
FROM Issue;
or you could store it when you need the actual value of issue_number
often....
Upvotes: 0