mysql concurrent insert

Usually when we insert into a table, it is done like this:
start transaction;
select * from t where id='x';
if not exist:
  insert into t(id,c) values('x',1);
else:
  update t set c=c+1 where id='x';
commit;


However, there will be a problem. If two concurrent inserts with id='x' arrive at the same time, they will not be found when selecting, and a primary key conflict will occur when inserting. How to make two concurrent inserts operate sequentially and the next insert is updated based on the result of the previous insert? Because in mysql RR mode, transactions are isolated from each other, if transaction 1 has been successfully inserted and committed, in transaction 2, no data is selected for the first time, and the result of the second select is the same (if there is no update). Another problem is if it perceives that another transaction has inserted data. I studied mysql and summarized it:
start transaction;
select * from t where id='x'; // get data
if exist:
 update t set c=c+1 where id='x'; //If it exists, it can be updated directly
 return;
rows=insert ignore into t(id,c) values('x',1); // insert ignore, if it does not exist, it will return 1 to indicate successful insertion, if it already exists, it will return 0
if rows==1:
  return; // Insert a row that does not currently exist, you can return
else rows==0: // Indicates that the row with id='x' already exists in the database when inserting
  update set d='xxx' where id='x'; // Update a column that is not too new, such as time, get the lock, because after the update, select can get the latest row and lock the record
  select * from t where id='x'; // The latest row is obtained at this time, and other updates are locked
  nc=c; // The c obtained by the program is the current latest c
  nc+=1; //Recalculate in the application
  update t set c=nc where id='x'; // finally update back
commit;


Use the mysql command to demonstrate:

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326913550&siteId=291194637