2012-03-30 2 views
11

각 클라이언트가 동시에 작동하기 때문에 클라이언트가 연결 해제 된 직후 트랜잭션을 롤백하도록 MySQL 서버를 만들어야합니다.연결이 끊어진/연결이 끊어진 트랜잭션에서 MySQL 롤백

START TRANSACTION; 
SELECT MAX(ID) FROM tblone FOR UPDATE; 
#... lock wait time out will occur here 
내가 설정 한

innodb_rollback_on_timeout 같은 MySQL의의 서버 옵션을 사용하여 : 클라이언트 B에

START TRANSACTION; 
SELECT MAX(ID) FROM tblone FOR UPDATE; 
#... then disconnect your connection to the server 

:이 문제는 클라이언트 A에

(AN InnoDB의 테이블 유형을 사용하여) 다음과 같은 재현 할 수 있습니다 두 클라이언트 모두에서 mysql 클라이언트 mysql --skip-reconnect. 네트워크에서 한 대의 서버와 두 대의 클라이언트를 사용하여이 작업을 시도했습니다. SELECT ... FOR UPDATE; 라인 이후에 물리적으로 네트워크 연결을 끊었습니다 (케이블을 뽑습니다). 다른 클라이언트가 즉시 트랜잭션 (잠금, 업데이트)에 tblone을 사용할 수있게해야합니다. 그러면 클라이언트 A의 연결이 끊어진 후에 서버가 클라이언트 A에 대한 트랜잭션을 롤백해야한다고 생각합니다.

+0

흥미로운 질문입니다. 나는 이것이 자동이라고 생각했다! 그래서 우리는'innodb_rollback_on_disconnect'와 같은 것을 필요로합니다. 그것은 좋을 것입니다. 그리고 저는 이것이 디폴트가되어야한다고 말하고 싶습니다! 그것은 mysql에 대한 합당한 변경 요청 일 것입니다. – TMS

답변

10

클라이언트를 물리적으로 연결 해제 할 때 (롤백을 일으킨) 일반 연결 끊기가 발생하지 않고 MySQL 프로토콜이 너무 수월하지 않으므로 서버는 클라이언트가없는 것을 결코 알 수 없습니다. 나는 이것이 클라이언트와 서버가 내부적으로 더 많이 이야기하는 다른 데이터베이스 시스템과 비교할 때 프로토콜의 결함이라고 생각한다.

어쨌든. 변경할 수있는 변수가 두 가지 있습니다. 그들은 기본적으로 동일하지만 다른 고객을 위해.

첫 번째는 wait_timeout이며 java 또는 php와 같은 응용 프로그램 클라이언트에서 사용됩니다.

다른 하나는 interactive_timeout이며이 두 경우 모두

초의 숫자 후 연결을 죽이고 그렇게 할 때하는 모든 모든 거래와 자료를 롤백에 서버 (당신의 검사 결과에서와 같이) mysql 클라이언트에 의해 사용된다 자물쇠.

+0

답장을 보내 주셔서 감사 드리며 두 옵션을 모두 사용해 보았습니다. 실험을 위해 60 초로 설정했지만 다른 문제가 발생합니다. 60 초 동안 사용하지 않으면 (유휴) 연결이 자동으로 닫히고 다음 쿼리에서 오류가 발생하고 (서버가 사라진 후) 자동으로 다시 연결됩니다. 연결을 확실히하기 위해 매 59 초마다 쿼리 할 코드를 작성해야합니까? 아니면 다른 방법이 있습니까? 60 초가 넘는 긴 쿼리는 프로세스 중간에 연결이 끊어 질 것입니까? – qsoft

+0

트랜잭션에서이 동작이 필요하기 때문에 트랜잭션 바로 전에 'SET SESSION wait_timeout = 60'과 같은 작업을 수행하고 커밋/롤백 후에 복원 할 수 있습니까? – qsoft

+0

트랜잭션을 시작하기 전에 저장 프로 시저 내에서 또는 별도의 명령문으로이를 변경할 수 있어야합니다. 그리고 유휴 연결이 닫혀있는 것이 옳습니다. 이것이 작동하는 방식입니다. 그러나 장시간 실행되는 쿼리는 "유휴"로 간주되지 않으므로 안전해야합니다 ('select 1, sleep (61) with dual'). –