복붙노트

[SQL] MySQL은 낙관적 잠금

SQL

MySQL은 낙관적 잠금

나는 MySQL은 낙관적 잠금에 대한 모든 정보를 찾을 수 없습니다. 그것이 충돌을 일으키는 동시에 데이터를 업데이트하는 두 명의 사용자를 중지하지 않습니다 - 나는 그러나, 동기화 된 두 개의 엔티티에 거래 킵 업데이트를 시작 읽어 보시기 바랍니다.

분명히 낙관적 잠금이 문제를 해결할 것인가? 어떻게 이런 일이 MySQL의에 적용됩니다. 이 거기에 SQL 구문 / 키워드인가? 또는 기본 동작을 MySQL을해야합니까?

고마워.

해결법

  1. ==============================

    1.요점은 낙관적 잠금이되지 MySQL 용이나 다른 사람을 위해, 데이터베이스 기능이되지 않는 것입니다 : 낙관적 잠금 표준 지침으로 DB를 사용하여 적용하는 방법입니다.

    요점은 낙관적 잠금이되지 MySQL 용이나 다른 사람을 위해, 데이터베이스 기능이되지 않는 것입니다 : 낙관적 잠금 표준 지침으로 DB를 사용하여 적용하는 방법입니다.

    의 아주 간단한 예제를 가지고 여러 사용자 / 클라이언트가 동시에 실행할 수있는 코드에서이 작업을 수행 할 수 있다고 가정 해 봅시다 :

    참고 : {중괄호 사이} 모든 코드는 SQL 측에서 응용 프로그램 코드에서 의도하지 (필요)입니다

    - SELECT iD, val1, val2
           FROM theTable
           WHERE iD = @theId;
     - {code that calculates new values}
     - UPDATE theTable
           SET val1 = @newVal1,
               val2 = @newVal2
           WHERE iD = @theId;
     - {go on with your other code}
    
    - SELECT iD, val1, val2
           FROM theTable
           WHERE iD = @theId;
     - {code that calculates new values}
     - UPDATE theTable
           SET val1 = @newVal1,
               val2 = @newVal2
           WHERE iD = @theId
               AND val1 = @oldVal1
               AND val2 = @oldVal2;
     - {if AffectedRows == 1 }
     -     {go on with your other code}
     - {else}
     -     {decide what to do since it has gone bad... in your code}
     - {endif}
    

    주 요점은 갱신 지시하고 해당 행 검사의 연속 수의 구조로된다. 그것은 누군가가 이미 당신이 SELECT 및 UPDATE 실행 한 경우 사이에있는 데이터를 수정 한 것을 코드의 실현하자이 두 가지입니다. 모두 거래없이 완료되었음을 공지 사항! 이것은이 매우 간단한 예입니다 그러나 이것은 낙관적 잠금의 키 포인트는 거래 자체 아니라고도 말한다 때문 (거래의 부재) 가능했습니다.

     - SELECT iD, val1, val2
           FROM theTable
           WHERE iD = @theId;
     - {code that calculates new values}
     - BEGIN TRANSACTION;
     - UPDATE anotherTable
           SET col1 = @newCol1,
               col2 = @newCol2
           WHERE iD = @theId;
     - UPDATE theTable
           SET val1 = @newVal1,
               val2 = @newVal2
           WHERE iD = @theId
               AND val1 = @oldVal1
               AND val2 = @oldVal2;
     - {if AffectedRows == 1 }
     -     COMMIT TRANSACTION;
     -     {go on with your other code}
     - {else}
     -     ROLLBACK TRANSACTION;
     -     {decide what to do since it has gone bad... in your code}
     - {endif}
    

    당신이 어떤 점에서 충돌을 확인하고 이미 수정 한 경우 충돌이 발생되어 발견하는 경우 있음이 마지막 예를 보여줍니다 다른 테이블 / 행 .. ..then 당신이 있기 때문에 수행 한 모든 변경 사항을 롤백 할 수있는 트랜잭션 시작. 분명히 그것은 (응용 프로그램이 무엇을하고 있는지 알고) 각각의 가능한 충돌에 대한 롤백에 대한 작업의 양이이 트랜잭션 경계를 넣어 어디 특별와의 충돌을 검사 위치를 결정에 따라 얼마나 큰를 결정하는 것은 여러분의 몫입니다 UPDATE + AffectedRows 확인.

    이 노력하면 우리는 순간부터 UPDATE를 수행 할 때 트랜잭션이 경우 우리는 순간을 분리했다. 그래서이 기간에하면 "다른 프로세스"를 수행 업데이 트를 어떻게됩니까? 정확히 분리 레벨의 세부 사항을 탐구 필요됩니까 (어떻게 각각의 엔진 관리)을 알고. READ_COMMITTED 업데이트 된 행 마이크로 소프트 SQL 서버의 경우 예를 들어 (가) 그래서 "다른 프로세스를"COMMIT까지 잠겨 아무것도 할 수없는 행에 (기다리고 유지), 둘 (그것은 단지 READ_COMMITTED 수 사실)을 선택합니다. "다른 과정"활동이 지연되기 때문에 그래서 그것의 UPDATE가 실패합니다.

     - SELECT iD, val1, val2, version
           FROM theTable
           WHERE iD = @theId;
     - {code that calculates new values}
     - UPDATE theTable
           SET val1 = @newVal1,
               val2 = @newVal2,
               version = version + 1
           WHERE iD = @theId
               AND version = @oldversion;
     - {if AffectedRows == 1 }
     -     {go on with your other code}
     - {else}
     -     {decide what to do since it has gone bad... in your code}
     - {endif}
    

    여기에 표시되는 대신 검사보다 값이 여전히 사람이 빨리 우리보다이었다 사이에 행을 변경 한 경우 우리가 볼 (우리가 업데이트를 할 때마다 수정) 전용 필드를 사용할 수있는 모든 필드에 대한 동일한 경우 우리의 SELECT 및 UPDATE. 여기서 트랜잭션의 부재는 제 1 실시 예와 같은 간략화로 인해 상기 버전 열 사용과 관련이 없다. 다시이 열 사용은 응용 프로그램 코드에서 구현이 아닌 데이터베이스 엔진 기능까지입니다.

    더 이것보다 내가 너무 오래이 답변을 할 것이라고 생각 다른 점들이있다 (이다 이미 너무 긴) 나는 단지 몇 가지 참고로 지금 그들을 말할 수 있도록 :

    격리 수준 값과 구현이 다를 수 있기 때문에 (이 사이트에서 평소와 같이) 최선의 충고는 사용 된 플랫폼 / 환경에서 테스트를 수행하는 것입니다.

    그것은 어려운 것처럼 보일 수 있지만, 실제로 그것은 두 개의 별도의 창을 사용하여 하나 하나의 명령을 각 하나에 거래를 시작하고 실행하는 모든 DB 개발 환경에서 아주 쉽게 수행 할 수 있습니다.

    어떤 시점에서 당신은 명령 실행이 무한정 계속 볼 수 있습니다. 다른 창에서이 호출 될 때 그 다음 COMMIT 또는 ROLLBACK 그것은 실행을 완료합니다.

    다음은 몇 가지 아주 기본적인 명령은 설명 된 바와 같이 테스트 할 준비가 된 것입니다.

    테이블 하나 개의 유용한 행을 만들기 위해 다음을 사용합니다 :

    CREATE TABLE theTable(
        iD int NOT NULL,
        val1 int NOT NULL,
        val2 int NOT NULL
    )
    INSERT INTO theTable (iD, val1, val2) VALUES (1, 2 ,3);
    

    그 다음 단계로 두 개의 서로 다른 창 단계에 다음과 같은 :

    BEGIN TRAN
    
    SELECT val1, val2 FROM theTable WHERE iD = 1;
    
    UPDATE theTable
      SET val1=11
      WHERE iD = 1 AND val1 = 2 AND val2 = 3;
    
    COMMIT TRAN
    

    당신이 생각하는 임의의 순서로 명령과 실행 순서의 순서를 변경합니다.

  2. from https://stackoverflow.com/questions/17431338/optimistic-locking-in-mysql by cc-by-sa and MIT license