2014-02-10 1 views
1

mysql db에서 트랜잭션을 수행 할 때 커밋 될 때까지 외부 소스에 의한 업데이트를 볼 수없는 진행중인 트랜잭션에 대해 이야기하고 있습니다. 따라서 변경이 가능하지만 트랜잭션이 트랜잭션을 볼 수 없거나 트랜잭션이 진행되는 동안 실제로 db를 업데이트 할 수 없다는 것을 의미합니다.트랜잭션이 다른 업데이트를 잠시 동안 방지하거나 숨길 수 있습니까?

다른 쿼리가 트랜잭션이 진행되는 동안 특정 테이블에 대해 아무 것도 변경하지 못하게해야하기 때문에. 지금 당장은 모든 테이블을 잠그고, 원 자성에 대한 트랜잭션을 시작하고, 커밋하고, 잠금을 해제합니다. 이것을하는 방법입니까?

내 테스트에서 격리 수준을 SERIALIZABLE로 설정하면 수동 테이블 잠금 및 잠금 해제와 동일한 결과를 얻는 것으로 보입니까? 이 올바른지?

답변

1

데이터베이스에 설정된 트랜잭션 격리 수준에 따라 달라질 수 있습니다. 레벨 here에 대한 자세한 내용을 볼 수 있습니다. 예를 들어, READ UNCOMMITTED의 경우, 다른 트랜잭션에 의해 커밋되지 않은 행을 실제로 읽을 수 있습니다. 이것은 보통 당신이 원하는 것을 원하지 않습니다.

다른 테이블을 선택하지 않으면 전체 테이블을 잠그는 것이 실제로 극단적 인 선택입니다. 내 권장 사항은 잠글 필요가있는 행을 고려한 다음 select for update 문을 사용하여 특정 행을 잠글 수있는 것입니다.

예를 들어 자원 테이블과 해당 자원에 대한 예약을 포함하는 스케줄 테이블이 있다고 가정합니다. 리소스를 예약 할 때 주어진 리소스에 대한 일정 테이블을 확인하여 원하는 시간에 사용할 수 있는지 확인해야합니다. 그러나이 작업은 병행 적으로 수행해야합니다. 즉, 자원의 가용성에 대한 일정표를 확인한 시간과 실제로 행을 일람표 테이블에 삽입하는 시간 사이에 원하는지 확인하려는 경우 다른 트랜잭션이 동일한 시간 (또는 겹치는 시간) 동안 자원을 예약하지 않도록하십시오.

업데이트 명령에 대한 선택을 사용하여이 작업을 수행 할 수 있습니다 : 다른 코드가 동일한 자원에 대한 저장 프로 시저를 발생 경우, 저장 프로 시저에서이 일을하고 가정

select * from resources where resource_name=’a’ for update; 

, 그것을 차단합니다 그 성명서에 그러면 리소스가 이중 예약되지 않습니다.

전체 리소스 테이블을 잠그면이 작업을 수행 할 수도 있습니다. 그러나 단일 리소스를 예약하는 데에만 관심이 있으므로이 작업을 수행 할 필요는 없습니다. 따라서 우리가 신경 써야 할 리소스 행을 잠그는 것만으로도 충분합니다.

MySQL의 경우 for 업데이트에 사용하는 열을 인덱싱해야합니다. 그렇지 않으면 전체 테이블이 잠길 것입니다.

모든 점은 항상 최대 동시성을 고려하는 것입니다. 즉, 필요 이상으로 잠그지 마십시오. 그렇지 않으면 응용 프로그램의 확장 성이 떨어지고 동시성이 제한됩니다.

+0

답장을 보내 주셔서 감사합니다. 하지만 '스토어드 프로 시저에서이 작업을한다고 가정하면 무엇을 의미합니까?' 이것을 다중 쿼리 문에서 첫 번째 행으로 실행하면 해당 명령문의 이후 기간 동안 행이 잠긴 상태로 유지됩니다. 절차에없는 경우에도 – user2520938

+0

예, 트랜잭션 기간 동안 행을 잠가 유지합니다. 여기서 코드에서 트랜잭션을 사용한다고 가정합니다. – dcp

관련 문제