我們有2個表Mysql的併發插入和鎖定
CREATE TABLE `Queue_token` (
`token_id` int(11) NOT NULL AUTO_INCREMENT,
`token_queue_id` int(11) NOT NULL,
`total_process_time` smallint(6) NOT NULL,
`token_user` int(11) DEFAULT NULL,
`created_on` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`join_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`join_time` time NOT NULL,
`app_type` tinyint(1) NOT NULL DEFAULT '1',
`is_advance` tinyint(1) NOT NULL DEFAULT '0',
`is_confirmed` tinyint(1) NOT NULL DEFAULT '1',
`token_user_group` int(11) DEFAULT NULL,
`uuid` binary(16) DEFAULT NULL,
PRIMARY KEY (`token_id`),
KEY `join_date_idx` (`join_date`),
KEY `queue_join_date` (`token_queue_id`,`join_date`),
KEY `token_user` (`token_user`),
KEY `fk_token_user_group` (`token_user_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `Live_token_sequence` (
`token_id` int(11) NOT NULL,
`queue_id` int(11) NOT NULL,
`sequence` int(11) NOT NULL,
`time_slot_id` mediumint(9) NOT NULL,
`time_slot_sequence` tinyint(4) NOT NULL,
`created_on` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`token_id`),
KEY `queue_sequence` (`queue_id`,`sequence`),
KEY `queue_time_slot` (`time_slot_id`),
CONSTRAINT `token_id_seq_fk` FOREIGN KEY (`token_id`) REFERENCES `Queue_token` (`token_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
基於我們生成用於Live_token_sequence表中的每個令牌的獨特序列中的Queue_token表產生一個日期的令牌的數量。
要生成序列,我們首先從Queue_token表中獲取標記的計數,並且生成的下一個標記獲取count + 1序列。
我們遇到了併發插入令牌變得相同的問題。如果我們嘗試使用SELECT FOR UPDATE,我們將面臨死鎖,因爲上面的count查詢也會與其他表進行連接。
我們如何去做這件事?
更新------ 計數查詢
```
select count(`sminq`.`Queue_token`.`token_id`)
from `sminq`.`Queue_token`
join `sminq`.`Live_token_sequence`
on `sminq`.`Queue_token`.`token_id` = `sminq`.`Live_token_sequence`.`token_id`
join `sminq`.`Calendar_time_slot`
on `sminq`.`Live_token_sequence`.`time_slot_id` = `sminq`.`Calendar_time_slot`.`slot_id`
join `sminq`.`Live_token_status` on `sminq`.`Queue_token`.`token_id` = `sminq`.`Live_token_status`.`token_id`
left outer join `sminq`.`Status_code`
on (`sminq`.`Live_token_status`.`token_status_id` = `sminq`.`Status_code`.`status_id`
and `sminq`.`Status_code`.`status_type` not in (?))
where (`sminq`.`Queue_token`.`join_date` >= ? and `sminq`.`Queue_token`.`join_date` < ?
and `sminq`.`Live_token_sequence`.`queue_id` = ? and `sminq`.`Calendar_time_slot`.`group_id` = ?) for update
包括新指標後,explin輸出
+------+-------------+---------------------+--------+---------------- ----------------------------------------------+------------+---------+--- -------------------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+---------------------+--------+---------------- ----------------------------------------------+------------+---------+--- -------------------------------------+------+-------------+
| 1 | SIMPLE | Calendar_time_slot | ref | slot_group,group_slot | group_slot | 4 | const | 6 | Using index |
| 1 | SIMPLE | Live_token_sequence | ref | PRIMARY,queue_sequence,queue_time_slot,queue_slot,slot_queue | queue_slot | 7 | const,sminq.Calendar_time_slot.slot_id | 1 | Using index |
| 1 | SIMPLE | Queue_token | eq_ref | PRIMARY,join_date_idx | PRIMARY | 4 | sminq.Live_token_sequence.token_id | 1 | Using where |
+------+-------------+---------------------+--------+---------------- ----------------------------------------------+------------+---------+--- -------------------------------------+------+-------------+
你指的是「作爲上面的計數查詢」? – Drew
http://dev.mysql.com/doc/refman/5.7/en/innodb-deadlocks-handling.html – GhostGambler
包含更新的查詢 – user160108