동시 액세스에서 테이블의 특정 행 수를 표시하는 방법

u6f6o

애플리케이션에는 cargo_items라는 테이블이 있습니다. 나중에 이러한 항목을 처리하는 일종의 대기열로 볼 수 있습니다. 처음에는 3000 개의 항목을 가져 와서 하나씩 처리하는 단일 작업이있었습니다. 나중에 누군가 같은 작업의 다른 인스턴스 3 개를 시작하기로 결정했습니다. 무슨 일이 일어 났는지는 아주 분명합니다. 많은 항목이 두 번 처리되었습니다.

내 임무는 동시에 많은 인스턴스가 실행중인 경우 이러한 프로세스가 올바르게 작동하도록하는 것입니다. 내가 지금 가고있는 해결책은 데이터베이스에있는 3000 개의 항목을 job_id로 표시하고 나중에 이러한 모든 항목을 가져 와서 다른 프로세스와 분리하여 처리하는 것입니다.

이 행에 플래그를 지정하는 현재 접근 방식은 다음과 같습니다.

UPDATE cargo_item item
SET job_id = 'SOME_UUID', job_ts = now()
FROM  ( 
   SELECT id
   FROM   cargo_item
   WHERE  state='NEW' AND job_id is null 
   LIMIT  3000
   FOR UPDATE
   ) sub
WHERE  item.id = sub.id;

기본적으로이 접근 방식은 업데이트를 위해 3000 개의 행을 잠급니다. 그래도 좋은 접근 방식인지 확실하지 않습니다.

다른 스레드 에서이 시나리오에 대한 권고 잠금 사용에 대해 읽었습니다.

현재 접근 방식에 대해 어떻게 생각하고 대신 자문 잠금을 사용합니까?

최신 정보

제안 된대로 다음과 같이 업데이트 문을 수정합니다.

UPDATE cargo_item item
SET job_id = 'SOME_UUID', job_ts = now()
FROM  ( 
   SELECT id
   FROM   cargo_item
   WHERE  state='NEW' AND job_id is null 
   ORDER  BY id
   LIMIT  3000
   FOR UPDATE
   ) sub
WHERE  item.id = sub.id;

힌트는 Thx Erwin과 Tometzky입니다. 그럼에도 불구하고 문제를 해결하려는 방식이 좋은 것인지 궁금합니다. 당신이 생각할 다른 접근 방식이 있습니까?

Erwin Brandstetter

관련 답변에서 다음을 참조하고 있습니다.

목표는 한 번에 한 행씩 잠그는 입니다. 동일한 트랜잭션에서 더 많은 행을 잠그려고하지 않는 한 교착 상태가 발생할 가능성없기 때문에 권고 잠금이 있든 없든 잘 작동 합니다.

한 번에 3000 개의 행 을 잠 그려 는 경우 예제가 다릅니다 . 모든 동시 쓰기 작업이 동일한 일관된 순서로 행을 잠그는 경우를 제외하고 교착 상태 발생할 가능성 이 있습니다 . 문서 별 :

교착 상태에 대한 최선의 방어는 일반적으로 데이터베이스를 사용하는 모든 응용 프로그램이 일관된 순서로 여러 개체에 대한 잠금을 획득하도록하여이를 방지하는 것입니다.

하위 쿼리에서 ORDER BY를 사용하여 구현하십시오.

UPDATE cargo_item item
SET job_id = 'SOME_UUID', job_ts = now()
FROM  ( 
   SELECT id
   FROM   cargo_item
   WHERE  state='NEW' AND job_id is null 
   ORDER  BY id
   LIMIT  3000
   FOR UPDATE
   ) sub
WHERE  item.id = sub.id;

모든 트랜잭션이 동일한 순서로 잠금을 획득하고 순서 지정 열의 동시 업데이트가 예상되지 않는 한 이는 안전하고 신뢰할 수 있습니다. ( 매뉴얼의이 장 끝에있는 노란색 "주의"상자를 읽으십시오 .) 따라서 id을 업데이트하지 않을 것이므로 귀하의 경우에 안전합니다 .

효과적으로 한 번에 하나의 클라이언트 만 이러한 방식으로 행을 조작 할 수 있습니다. 동시 트랜잭션은 동일한 (잠긴) 행을 잠그고 첫 번째 트랜잭션이 완료 될 때까지 기다립니다.

권고 잠금 은 동시 트랜잭션이 많거나 매우 오래 실행되는 경우에 유용합니다 (그렇지 않은 것 같음). 몇 개만 있으면 위의 쿼리 만 사용하고 동시 트랜잭션이 차례를 기다리도록하는 것이 전반적으로 더 저렴합니다.

올인원 업데이트

동시 액세스는 설정 자체에서 문제가되지 않는 것 같습니다. 동시성은 현재 솔루션에서 발생하는 문제입니다.

대신 단일UPDATE . n각 UUID 번호 배치 (예 : 3000)를 할당하고 한 번에 모두 업데이트합니다. 가장 빨라야합니다.

UPDATE cargo_item c
SET    job_id = u.uuid_col
     , job_ts = now()
FROM  (
   SELECT row_number() OVER () AS rn, uuid_col
   FROM   uuid_tbl WHERE  <some_criteria>  -- or see below
   ) u
JOIN (
   SELECT (row_number() OVER () / 3000) + 1 AS rn, item.id 
   FROM   cargo_item
   WHERE  state = 'NEW' AND job_id IS NULL
   FOR    UPDATE   -- just to be sure
   ) c2 USING (rn)
WHERE  c2.item_id = c.item_id;

주요 포인트

  • 정수 나누기가 잘립니다. 처음 3000 개 행에 대해 1 개, 다음 3000 개 행에 대해 2 개를 얻습니다. 기타

  • 나는 임의로 행을 선택 하고 특정 행을 할당 ORDER BY하기 row_number()위해 창에서 신청할 수 있습니다 .

  • 디스패치 할 UUID 테이블 ( uuid_tbl) 이없는 경우 VALUES표현식을 사용 하여 제공합니다. 예.

  • 3000 행의 일괄 처리를 얻습니다. 할당 할 3000의 배수를 찾지 못하면 마지막 배치는 3000이 부족합니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

특정 열의 HTML 테이블에 행 번호를 표시하는 방법은 무엇입니까?

분류에서Dev

특정 테이블 행의 jQuery 데이터 테이블에서 Cell에 액세스하는 방법

분류에서Dev

레거시 jQuery 데이터 테이블에서 특정 행의 행 ID를 얻는 방법

분류에서Dev

ID를 인수로 사용하여 SQL 데이터베이스의 특정 행을 표시하는 방법

분류에서Dev

특정 행 수에 <문자열> 세트를 표시하는 방법

분류에서Dev

데이터 테이블에 특정 데이터를 표시하는 방법

분류에서Dev

테이블의 열을 정렬 할 수 있지만 결정된 위치에 특정 행을 표시 할 수있는 방법이 있습니까?

분류에서Dev

DataGridView에서 조인 된 테이블의 정보를 표시하는 방법

분류에서Dev

Ajax 게시물에서 특정 테이블 행 데이터를 사용하는 방법

분류에서Dev

테이블에 특정 양의 데이터 만 표시하는 방법

분류에서Dev

테이블 행의 onclick에서 자바 스크립트 함수 호출에서 jquery로 테이블 행의 강조 표시를 설정하는 방법은 무엇입니까?

분류에서Dev

MySQL : 테이블에 특정 수의 빈 행을 삽입하는 방법

분류에서Dev

자바 스크립트를 사용하여 테이블의 특정 행에 대한 제어에 액세스하는 방법은 무엇입니까?

분류에서Dev

android studio에서 특정 시간 동안 스레드를 실행하는 방법

분류에서Dev

매트 테이블의 행을 클릭 한 후 새 페이지에 다른 모든 세부 정보를 표시하는 방법

분류에서Dev

Java를 사용하여 MySQL의 특정 행에 액세스하는 방법

분류에서Dev

Android에서 특정 수의 알림을 표시하는 방법

분류에서Dev

Swift의 특정 인덱스에 collectionView를 표시하는 방법

분류에서Dev

R에서 자동 프로세스 (예 : for 루프 등)를 사용하여 벡터 간의 특정 값 시퀀스에 대한 일치 행을 찾는 방법

분류에서Dev

특정 키워드를 포함하는 텍스트 파일의 행을 표시하는 방법-CMD

분류에서Dev

SQL 테이블의 특정 행에 대한 사용자 액세스를 확인하는 방법은 무엇입니까?

분류에서Dev

Android의 Listview에서 특정 수의 레코드를 표시하는 방법

분류에서Dev

특정 테이블에서 행을 "복제"하는 방법 (새 ID를 자동 할당하는 동안)?

분류에서Dev

Servlet의 요청 매개 변수에 따라 jsp에서 특정 테이블 헤드를 표시하는 방법은 무엇입니까?

분류에서Dev

하나의 테이블 행에 유사한 JSON 데이터를 표시하는 방법

분류에서Dev

M : m 테이블 SQL에서 정확히 세 가지 케이스로 ID를 표시하는 방법

분류에서Dev

M : m 테이블 SQL에서 정확히 세 가지 케이스로 ID를 표시하는 방법

분류에서Dev

데이터베이스에서 특정 세부 정보를 표시하는 방법

분류에서Dev

액세스 테이블의 일련 번호 필드를 재설정하는 방법은 무엇입니까? (1에서 시작하지 않음)

Related 관련 기사

  1. 1

    특정 열의 HTML 테이블에 행 번호를 표시하는 방법은 무엇입니까?

  2. 2

    특정 테이블 행의 jQuery 데이터 테이블에서 Cell에 액세스하는 방법

  3. 3

    레거시 jQuery 데이터 테이블에서 특정 행의 행 ID를 얻는 방법

  4. 4

    ID를 인수로 사용하여 SQL 데이터베이스의 특정 행을 표시하는 방법

  5. 5

    특정 행 수에 <문자열> 세트를 표시하는 방법

  6. 6

    데이터 테이블에 특정 데이터를 표시하는 방법

  7. 7

    테이블의 열을 정렬 할 수 있지만 결정된 위치에 특정 행을 표시 할 수있는 방법이 있습니까?

  8. 8

    DataGridView에서 조인 된 테이블의 정보를 표시하는 방법

  9. 9

    Ajax 게시물에서 특정 테이블 행 데이터를 사용하는 방법

  10. 10

    테이블에 특정 양의 데이터 만 표시하는 방법

  11. 11

    테이블 행의 onclick에서 자바 스크립트 함수 호출에서 jquery로 테이블 행의 강조 표시를 설정하는 방법은 무엇입니까?

  12. 12

    MySQL : 테이블에 특정 수의 빈 행을 삽입하는 방법

  13. 13

    자바 스크립트를 사용하여 테이블의 특정 행에 대한 제어에 액세스하는 방법은 무엇입니까?

  14. 14

    android studio에서 특정 시간 동안 스레드를 실행하는 방법

  15. 15

    매트 테이블의 행을 클릭 한 후 새 페이지에 다른 모든 세부 정보를 표시하는 방법

  16. 16

    Java를 사용하여 MySQL의 특정 행에 액세스하는 방법

  17. 17

    Android에서 특정 수의 알림을 표시하는 방법

  18. 18

    Swift의 특정 인덱스에 collectionView를 표시하는 방법

  19. 19

    R에서 자동 프로세스 (예 : for 루프 등)를 사용하여 벡터 간의 특정 값 시퀀스에 대한 일치 행을 찾는 방법

  20. 20

    특정 키워드를 포함하는 텍스트 파일의 행을 표시하는 방법-CMD

  21. 21

    SQL 테이블의 특정 행에 대한 사용자 액세스를 확인하는 방법은 무엇입니까?

  22. 22

    Android의 Listview에서 특정 수의 레코드를 표시하는 방법

  23. 23

    특정 테이블에서 행을 "복제"하는 방법 (새 ID를 자동 할당하는 동안)?

  24. 24

    Servlet의 요청 매개 변수에 따라 jsp에서 특정 테이블 헤드를 표시하는 방법은 무엇입니까?

  25. 25

    하나의 테이블 행에 유사한 JSON 데이터를 표시하는 방법

  26. 26

    M : m 테이블 SQL에서 정확히 세 가지 케이스로 ID를 표시하는 방법

  27. 27

    M : m 테이블 SQL에서 정확히 세 가지 케이스로 ID를 표시하는 방법

  28. 28

    데이터베이스에서 특정 세부 정보를 표시하는 방법

  29. 29

    액세스 테이블의 일련 번호 필드를 재설정하는 방법은 무엇입니까? (1에서 시작하지 않음)

뜨겁다태그

보관