2010-12-30 4 views
4

MySQL은 "for update"키워드를 지원합니다. 다음은 예상대로 작동하는지 테스트 한 방법입니다. 2 개의 브라우저 탭을 열고 다음 명령을 하나의 창에서 실행했습니다. 다른 창에서 업데이트 용 MySQL


mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select * from myxml where id = 2 for update; 
.... 
mysql> update myxml set id = 3 where id = 2 limit 1; 
Query OK, 1 row affected, 1 warning (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> commit; 
Query OK, 0 rows affected (0.08 sec) 

, 나는 트랜잭션을 시작하고 같은 레코드의 업데이트 잠금을 찍어 보았습니다.

mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select * from myxml where id = 2 for update; 
Empty set (43.81 sec) 

위의 예에서 볼 수 있듯이 트랜잭션이 트랜잭션이 끝난 후에는 창 없음 1. 다른 응용 프로그램에 의해 처리되고 있었다, 나는 43 초 기록을 선택할 수없는, 내가 선택할 수있어 레코드가 있지만 id 2가 처음 실행 된 트랜잭션에 의해 id 3으로 변경되었으므로 레코드가 리턴되지 않습니다.

제 질문은 "for update"문법의 단점은 무엇입니까? 창 1에서 실행중인 트랜잭션을 커밋하지 않으면 레코드가 잠긴 것입니까?

+0

귀하의 요구 사항에 매우 좌우되는 "단점"을 참조하십시오. 자물쇠가 필요한 부분에 대해 더 자세히 설명해 주시겠습니까? –

+0

나는 거의 모든 질문에 대한 답변을 수락했다. 원하는 경우 확인할 수 있습니다. 사람들에게 불가능한 일을하도록 요청하는 것을 멈추십시오 :) – shantanuo

답변

3

예, 트랜잭션 # 1이 커밋하지 않으면 연결이 끊어 지거나 innodb가 교착 상태 감지로 인해 트랜잭션을 롤백하지 않는 한 해당 레코드는 영구적으로 잠 깁니다.

하지만, ID 2 이후

먼저 를 실행 된, 어떤 기록이 반환 된 트랜잭션 ID 3 로 변경되었습니다.

원하지 않는가요? 그렇지 않다면 SELECT ... FOR UPDATE을 적절하게 사용하고 있지 않습니다. http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

+0

예, 이것이 제가 원하는 것입니다. 하지만 커밋이 어떤 이유로 인해 발생하지 않으면 잠금을 원하지 않습니다. 사용자가 연결을 중단했습니다. 게다가, 주어진 시간에 얼마나 많은 레코드가 업데이트를 위해 잠겨 있는지를 알 수있는 방법이 있습니까? – shantanuo

+1

@shantanuo 사용자가 연결을 중단하면 트랜잭션이 자동으로 롤백됩니다. –

+0

트랜잭션을 사용하면 대기중인 작업이 있다는 사실을 처리해야합니다. 하지만 시간 제한 기간을 변경할 수 있습니다. http://dev.mysql.com/doc/refman/5.0/en/innodb-parameters.html#sysvar_innodb_lock_wait_timeout – regilero