mysql 生成uid_MySQL死锁与存储过程生成UID

bd96500e110b49cbb3cd949968f18be7.png

I have a stored procedure generating UID's from a "ticket" table, but under load I'm getting lots of deadlocks. I'm calling this procedure many times from multiple concurrent connections whenever my task needs a new UID.

BEGIN

DECLARE a_uid BIGINT(20) UNSIGNED;

START TRANSACTION;

SELECT uid INTO a_uid FROM uid_data FOR UPDATE; # Lock

INSERT INTO uid_data (stub) VALUES ('a') ON DUPLICATE KEY UPDATE uid=uid+1;

SELECT a_uid+1 AS `uid`;

COMMIT;

END

I did consider using:

BEGIN

REPLACE INTO uid_data (stub) VALUES ('a');

SELECT LAST_INSERT_ID();

END

However I wasn't sure if that would be safe with concurrent connections as there's no locking, unlike the first procedure with the SELECT FOR UPDATE.

Here's the table:

mysql> DESCRIBE uid_data;

+-------+---------------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------+---------------------+------+-----+---------+----------------+

| uid | bigint(20) unsigned | NO | PRI | NULL | auto_increment |

| stub | char(1) | NO | UNI | NULL | |

+-------+---------------------+------+-----+---------+----------------+

I've setup for read-committed transaction isolation:

mysql> SHOW VARIABLES LIKE 'tx_isolation';

+---------------+-----------------+

| Variable_name | Value |

+---------------+-----------------+

| tx_isolation | READ-COMMITTED |

+---------------+-----------------+

Here's what I'm getting back from SHOW ENGINE INNODB STATUS;

...

... dozens and dozens of the following record locks...

Record lock, heap no 1046 PHYSICAL RECORD: n_fields 2; compact format; info bits 32

0: len 1; hex 61; asc a;;

1: len 8; hex 00000000000335f2; asc 5 ;;

Record lock, heap no 1047 PHYSICAL RECORD: n_fields 2; compact format; info bits 32

0: len 1; hex 61; asc a;;

1: len 8; hex 00000000000335f1; asc 5 ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 13 page no 4 n bits 1120 index `stub` of table `my_db`.`uid_data` trx id 13AA89 lock_mode X waiting

Record lock, heap no 583 PHYSICAL RECORD: n_fields 2; compact format; info bits 32

0: len 1; hex 61; asc a;;

1: len 8; hex 00000000000334a8; asc 4 ;;

*** WE ROLL BACK TRANSACTION (1)

I'd be grateful if someone could explain what's happening and how they can be avoided.

解决方案

Do this:

CREATE TABLE tickets

(

uid serial

)

Then to get the next uid:

BEGIN

INSERT INTO tickets VALUES (NULL);

SELECT LAST_INSERT_ID();

END

uid serial is equivalent to

uid BIGINT(20) UNSIGNED NOT NULL PRIMARY KEY auto_increment

You shouldn't experience any deadlocks with this approach and can throw as many connections at it as you like.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值