의 중복 질문 :
/programming/129329/optimistic-vs-pessimistic-locking
위 링크에서 답변 복사 / 붙여 넣기 :
낙관적 잠금은 레코드를 읽고 버전 번호를 기록한 후 레코드를 다시 쓰기 전에 버전이 변경되지 않았는지 확인하는 전략입니다. 레코드를 다시 쓰면 버전의 업데이트를 필터링하여 최신 상태인지 확인합니다. (즉, 버전을 확인하고 레코드를 디스크에 쓸 때 사이에 업데이트되지 않았습니다) 한 번에 버전을 업데이트하십시오.
레코드가 더러 우면 (즉, 다른 버전과 다름) 트랜잭션을 중단하고 사용자가 다시 시작할 수 있습니다.
이 전략은 세션의 데이터베이스에 대한 연결을 반드시 유지할 필요가없는 대용량 시스템 및 3 계층 아키텍처에 가장 적합합니다. 이 상황에서는 연결이 풀에서 이루어 지므로 클라이언트가 실제로 데이터베이스 잠금을 유지할 수 없으며 한 액세스에서 다음 액세스로 동일한 연결을 사용하지 않을 수 있습니다.
비관적 잠금은 레코드가 끝날 때까지 독점 사용을 위해 레코드를 잠그는 것입니다. 낙관적 잠금보다 무결성이 훨씬 뛰어나지 만 교착 상태를 피하려면 응용 프로그램 디자인에주의해야합니다. 비관적 잠금을 사용하려면 일반적으로 2 계층 클라이언트 서버 응용 프로그램에서와 같이 데이터베이스에 직접 연결하거나 연결과 독립적으로 사용할 수있는 외부에서 사용 가능한 트랜잭션 ID가 필요합니다.
후자의 경우 TxID로 트랜잭션을 연 다음 해당 ID를 사용하여 다시 연결합니다. DBMS는 잠금을 유지하고 TxID를 통해 세션을 다시 선택할 수 있습니다. 이는 2 단계 커밋 프로토콜 (예 : XA 또는 COM + 트랜잭션)을 사용하는 분산 트랜잭션이 작동하는 방식입니다.
편집 (성능 질문에 대한 추가 정보 추가) :
현명한 성능은 환경에 따라 다릅니다. 다음 사항을 고려하여 결정하십시오.
대부분의 상황에서 동시성으로 인해 낙관적입니다. 그러나 RDBMS 및 환경에 따라 성능이 다소 떨어질 수 있습니다. 일반적으로 낙관적 잠금을 사용하면 값을 어딘가에 행 버전 화해야합니다.
예를 들어 MS SQL Server를 사용하면 TempDB로 이동하고 열의 끝에 12-14 바이트 사이에 추가됩니다. Snapshot Isolation과 같은 격리 수준으로 낙관적 잠금을 설정하면 조각화가 발생할 수 있으며 마지막에 행에 추가 데이터가 추가되어 페이지가 거의 꽉 차서 페이지가 분할 될 수 있으므로 채우기 비율을 조정해야합니다. 당신의 성능. TempDB가 최적화되지 않은 경우 빠르지 않습니다.
체크리스트는 다음과 같습니다.
- -행 버전 관리 형식을 처리하기에 충분한 IO / 리소스가 있습니까? 그렇지 않은 경우 오버 헤드가 추가됩니다. 그렇다면 쓰기를 위해 데이터를 잠그는 동안 데이터를 자주 읽는 경우 읽기와 쓰기에서 동시성이 향상됩니다 (쓰기는 여전히 쓰기를 차단하지만 읽기는 더 이상 쓰기를 차단하지 않으며 그 반대도 마찬가지 임)
- -코드가 교착 상태에 취약하거나 잠금이 발생합니까? 긴 잠금 또는 많은 교착 상태가 발생하지 않으면 낙관적 잠금의 추가 오버 헤드로 인해 속도가 빨라지지는 않지만 대부분의 경우 여기서는 밀리 초를 말합니다.
- -DB가 크거나 (또는 매우 제한된 하드웨어에있는) RDBMS에 따라 데이터 페이지가 거의 가득 찬 경우 주요 페이지 분할 및 데이터 조각화가 발생할 수 있으므로 전원을 켠 후에 다시 색인화를 고려해야합니다.
이것들은이 문제에 대한 나의 생각이며, 지역 사회로부터 더 많은 것을들을 수 있도록 열려 있습니다.