이 기사에서는 MySQL이 교착 상태를 일괄적으로 업데이트하는 방법에 대해 주로 설명합니다. 관심 있는 친구는 아래를 참조해 보세요.
테이블 구조는 다음과 같습니다.
CREATE TABLE `user_item` ( `id` BIGINT(20) NOT NULL, `user_id` BIGINT(20) NOT NULL, `item_id` BIGINT(20) NOT NULL, `status` TINYINT(4) NOT NULL, PRIMARY KEY (`id`), KEY `idx_1` (`user_id`,`item_id`,`status`)) ENGINE=INNODB DEFAULT CHARSET=utf-8
SQL 문은 다음과 같습니다.
update user_item set status=1 where user_id=? and item_id=?
원인 분석:
mysql的事务支持与存储引擎有关,MyISAM不支持事务,INNODB支持事务,更新时采用的是行级锁。这里采用的是INNODB做存储引擎,意味着会将update语句做为一个事务来处理。前面提到行级锁必须建立在索引的基础,这条更新语句用到了索引idx_1,所以这里肯定会加上行级锁。 行级锁并不是直接锁记录,而是锁索引,如果一条SQL语句用到了主键索引,mysql会锁住主键索引;如果一条语句操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引。
이 업데이트 문은 다음 단계를 수행합니다.
기본 키가 아니기 때문에 인덱스가 사용되면 먼저 idx_1을 얻어야 합니다. 그런 다음 행 수준 잠금
이 기본 키를 기반으로 업데이트되므로 기본 키에 대한 행 수준 잠금
을 얻어야 합니다. 업데이트가 완료되면 모든 잠금을 커밋하고 해제합니다.
1단계와 2단계 사이에 update user_item .....여기서 id=? 및 user_id=? 명령문이 갑자기 삽입되면 이 명령문은 먼저 기본 키 인덱스를 잠근 다음 idx_1을 잠급니다.
한 문은 idx_1에 대한 잠금을 획득하고 기본 키 인덱스에 대한 잠금을 기다립니다. 다른 문은 기본 키에 대한 잠금을 획득하고 idx_1에 대한 잠금을 기다리므로 교착 상태가 발생합니다.
해결책:
select id from user_item where user_id=? and item_id=?
update user_item set status=? where id=? and user_id=?
배치 주기에서 첫 번째와 두 번째 단계를 반복하세요
추천 학습: " MySQL 비디오 튜토리얼 》
위 내용은 MySQL이 일괄 교착 상태를 업데이트하는 방법을 자세히 설명하는 기사의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!