"SELECT FOR UPDATE"는 행이 없을 때 다른 연결을 삽입할 수 없도록 합니까?
나는 관심이 있다.SELECT FOR UPDATE을 사용법
예
★★★FooBar 있습니다.foo ★★★★★★★★★★★★★★★★★」bar,foo에는 고유한 인덱스가 있습니다.
- 쿼리 ★★★★★★
SELECT bar FROM FooBar WHERE foo = ? FOR UPDATE - 첫 번째 쿼리가 0 행을 반환하는 경우 쿼리를 발행합니다.
INSERT INTO FooBar (foo, bar) values (?, ?)
,INSERT인덱스 위반을 일으키거나SELECT FOR UPDATE을을수 을을?
SQL Server(2005/8), Oracle 및 MySQL에서의 동작에 관심이 있습니다.
MySQL
업데이트를 하려면 ...을 선택하십시오.
(auto-commit)와의 트랜잭션을 SELECT ... FOR UPDATE그럼 1개의 세션이 특정 레코드를 일시적으로 잠글 수 있으므로 다른 세션에서는 레코드를 갱신할 수 없습니다.같은될 수 .UPDATE같은 레코드로 트랜잭션을 커밋 또는 롤백합니다.그러면 레코드를 잠그고 다른 비즈니스 로직을 수행하는 동안 다른 세션에서 레코드를 업데이트할 수 없습니다.
이것은 잠금으로 실현됩니다.InnoDB는 레코드를 잠그기 위해 인덱스를 사용하기 때문에 기존 레코드를 잠그기만 하면 됩니다.
삽입으로 업데이트하려면 ...을 선택하십시오.
「」를 하려면 , 「」를 합니다.SELECT ... FOR UPDATEINSERT아직 존재하지 않는 레코드의 인덱스를 잠그려면 어떻게 해야 합니까? 「」를 경우.REPEATABLE READInnoDB는 갭락도 활용합니다.당신이 알고 있는 한id(또는 ID 범위까지) 잠글 수 있도록 InnoDB는 갭을 잠글 수 있으므로 작업이 완료될 때까지 갭에 다른 레코드를 삽입할 수 없습니다.
의 '' ''가id컬럼이고 은 자동 입력 컬럼입니다.SELECT ... FOR UPDATEINSERT INTO어떤 가 될 수 있습니다.왜냐하면 당신은 새로운 것이 무엇인지 모르기 때문입니다.id, 알고 때문에id 것, 삽입하고 싶은 것, 삽입하고 싶은 것.SELECT ... FOR UPDATEINSERT과가있있 있있있다다
경고
에서는, 「」가 .SELECT ... FOR UPDATE존재하지 않는 레코드의 경우 다른 트랜잭션은 차단되지 않습니다.따라서 두 개의 트랜잭션이 모두 처리되는 경우SELECT ... FOR UPDATE존재하지 않는 동일한 인덱스 레코드에 대해 둘 다 잠금을 받게 되고 두 거래 모두 레코드를 업데이트할 수 없게 됩니다.실제로 시도하면 교착 상태가 감지됩니다.
따라서 교착 상태를 처리하지 않으려면 다음을 수행합니다.
삽입처...
트랜잭션을 시작하고INSERT비즈니스 로직을 수행하고 트랜잭션을 커밋하거나 롤백합니다.이 작업을 마치자마자INSERT첫 번째 거래의 존재하지 않는 레코드 인덱스에서 다른 모든 트랜잭션이 차단됩니다.INSERT동일한 고유 인덱스를 가진 레코드첫 번째 트랜잭션이 삽입을 커밋한 후 두 번째 트랜잭션이 동일한 인덱스를 가진 레코드를 삽입하려고 하면 "복제 키" 오류가 발생합니다.적절히 처리한다.
공유 모드에서 잠금 선택...
를 한 경우LOCK IN SHARE MODEbefore INSERT되었지만 아직 않은 " " "는 "를 의미합니다.SELECT ... LOCK IN SHARE MODE이전 트랜잭션이 완료될 때까지 차단됩니다.
따라서 특히 비즈니스 로직을 수행하거나 롤백하기 전에 잠금을 잠시 동안 유지한 상태에서 키 오류가 중복될 가능성을 줄이려면 다음 절차를 따릅니다.
SELECT bar FROM FooBar WHERE foo = ? LOCK FOR UPDATE- 레코드가 반환되지 않으면
INSERT INTO FooBar (foo, bar) VALUES (?, ?)
Oracle에서 SELECT ... FOR UPDATE는 존재하지 않는 행에 영향을 주지 않습니다(이 문은 No Data Found 예외를 발생시킵니다).INSERT 문을 사용하면 고유 키/프라이머리 키 값의 중복을 방지할 수 있습니다.동일한 키 값을 삽입하려는 다른 트랜잭션은 첫 번째 트랜잭션이 커밋되거나(이 때 차단된 트랜잭션이 중복 키 오류를 발생) 롤백될 때까지 차단됩니다(이 때 차단된 트랜잭션이 계속됩니다).
Oracle의 경우:
세션 1
create table t (id number);
alter table t add constraint pk primary key(id);
SELECT *
FROM t
WHERE id = 1
FOR UPDATE;
-- 0 rows returned
-- this creates row level lock on table, preventing others from locking table in exclusive mode
세션 2
SELECT *
FROM t
FOR UPDATE;
-- 0 rows returned
-- there are no problems with locking here
rollback; -- releases lock
INSERT INTO t
VALUES (1);
-- 1 row inserted without problems
SQL Server에 대한 자세한 분석을 작성했습니다: 동시성을 유지하는 수정 개발
어쨌든 직렬화 가능한 격리 수준을 사용해야 하며, 실제로 스트레스 테스트를 수행해야 합니다.
Server가 .FOR UPDATE는 커서 내의 현재 됩니다.업데이트하다
그...FOR UPDATE가 INSERT따라서 SQL Server에는 해당되지 않는다는 답변이라고 생각합니다.
그럼 이제 '', '모사', '모사'를 할 수 있을 것 요.FOR UPDATE트랜잭션 및 잠금 전략에 대한 동작입니다.하지만, 그것은 당신이 찾고 있는 것 이상일 수도 있습니다.
언급URL : https://stackoverflow.com/questions/3601895/does-select-for-update-prevent-other-connections-inserting-when-the-row-is-not
'programing' 카테고리의 다른 글
| JSON.parse 예기치 않은 문자 오류 (0) | 2023.03.10 |
|---|---|
| AngularJS의 Run Block에서 약속을 기다리는 방법 (0) | 2023.03.10 |
| Angular를 사용하여 형식 유효성 검사에서 두 입력 값 비교JS (0) | 2023.03.10 |
| 빈 초기화 완료 후 메서드 호출 방법 (0) | 2023.03.10 |
| 리액트 네이티브로 함수가 가득한 도우미 파일을 작성하려면 어떻게 해야 합니까? (0) | 2023.03.10 |