2017-09-26 13 views
0

ID를 검색하려면 먼저 두 개의 결과 쿼리에서 select와 then update를 수행합니다.저장 프로 시저와 표준 선택 업데이트, 잠금 방지

문제는 잠긴 행에 문제가 있다는 것입니다. 나는이 문장을 모두 저장하고 선택과 업데이트를 하나의 저장 프로 시저에서 사용하여 잠금에 도움이된다는 것을 읽었다. 사실입니까? 내가 실행

쿼리는 다음과 같습니다

select counter 
from dba.counter_list 
where table_name = :TableName 

update dba.counter_list 
set counter = :NewCounter 
where table_name = :TableName 

문제는 그 여러 사용자가 동일한 행을 선택하고는 동일한 행을 업데이트하는 것도 가능 일어날 수 있다는 것입니다.

+0

기존 코드를 게시하고 잠금 장치에 대한 정확한 문제를 설명하십시오. –

+0

@ PM77-1 –

+0

잠금은 ** 벤더에 따라 다르다. ** - mysql, postgresql, sql-server, oracle 중 어느 것을 사용 하는지를 지정하는 태그를 추가한다. '또는'db2' - 또는 완전히 다른 것. –

답변

0

가정 :

  • 당신은 당신이 업데이트를 수행 이외의 목적을 위해 이전 counter 값을 할 수 있습니다 counter
  • 에 대한
  • 당신의 select 반환 단일 값을 사이베이스 ASE를 사용하는

다음과 같은 경쟁 조건을 없애야하는 update 문을 고려하십시오. 여러 사용자가 동시에 당신의 select/update 로직을 실행하는 발생합니다

declare @counter int   -- change to the appropriate datatype 

update dba.counter_list 
set  @counter = counter,  -- grab current value 
     counter = :NewCounter -- set to new value 
where table_name = :TableName 

select @counter    -- send previous counter value to client 
  • update 원하는 행에 대한 배타적 잠금을 얻는다 (또는 페이지/테이블 테이블 디자인과 잠금 방식에 따라 다름) 독점 잠금과
  • 현재 값을 검색하고 하나의 문으로 새 값을 설정할 수있어 장소 당신이 t를 제출 여부

그는 SQL 배치 또는 저장된 proc 호출을 통해 위에 결정할 당신과 당신의 DBA까지입니다 ...다음에 기회가 명령문 캐시가 무효 인 경우

  • 는 SQL 배치는
  • 하는 명령문 캐시가 활성화 된 경우는 데이터 서버에 제출 될 때마다 컴파일해야합니다, 당신은 정기적으로이 SQL 일괄 제출 이전의 쿼리 계획은 여전히 ​​명령문/프로 시저 캐시에 남아 있으므로 이전에 저장된 proc (쿼리) 계획의 복사본이 프로 시저 캐시에없는 경우에는 (비싼) 컴파일 단계를 생략하므로
  • 다음과 같은 경우 (비용이 많이 드는) 컴파일 단계가 발생합니다. 프로 시저 cahe
  • 에 프로 시저 (proc) 쿼리 계획로드 프로 시저를 저장하면 일반적으로 다음과 같은 경우에 쉽게 교체 할 수 있습니다. (수정 및 프론트 엔드 응용 프로그램을 컴파일하는 것과는 대조적으로)
  • ... SQL 배치 대 저장된 proc (대문자 vs prepared statement?)에 대한 선호하는 인수를 추가 하시겠습니까? ? ...
+0

도움을 주셔서 대단히 감사합니다. 매우 잘 설명하고 설명했습니다! –

0

counter_list에 여러 클라이언트가 동시에 액세스하는 테이블이 있습니까?

OLTP의 모범 사례는 한 트랜잭션에서 업데이트 논리를 수행 할 저장 프로 시저를 호출하는 것입니다.

dba.counter_list 테이블에 table_name 열에 대한 인덱스가 있는지 확인하십시오. 행 레벨이 잠겨 있는지 확인하십시오.