문제

다음 (위생) 코드는 때때로 이러한 오류를 생성합니다.

'database.dbo.table'이 존재하지 않거나 허가가 없기 때문에 테이블을 삭제할 수 없습니다.
데이터베이스에는 이미 '테이블'이라는 객체가 있습니다.

begin transaction  
    if exists (select 1 from database.Sys.Tables where name ='Table') 
        begin drop table database.dbo.Table end 

    Select top 3000 *
    into database.dbo.Table
    from OtherTable
commit

select * from database.dbo.Table

코드는 동시에 여러 번 실행할 수 있습니다. 왜 그것이 깨지는 지 아는 사람이 있습니까?

도움이 되었습니까?

해결책

코드의 어느 부분 에서이 리소스에 대한 여러 액세스를 방지합니까?

begin transaction  
    if exists (select 1 from database.Sys.Tables where name ='Table') 
        begin drop table database.dbo.Table end 

    Select top 3000 *
    into database.dbo.Table
    from OtherTable
commit

트랜잭션을 시작하지 않습니다. 테이블에 추가 된 행에 커밋/롤백 시나리오에 대해서만 설정됩니다.

(존재하는 경우, 드롭)는 (select..into)과 함께 테이블의 재창조와 함께 인종 조건입니다. 한 번에 해당 코드에 빠지는 사람들은 가장 확실하게 모든 종류의 오류를 유발할 것입니다. 어떤 사람들은 다른 사람들이 방금 파괴 한 테이블을 만들고, 다른 일부는 더 이상 존재하지 않는 테이블을 떨어 뜨리고, 다른 일부는 삽입하는 테이블을 떨어 뜨립니다. u!

다른 사람의 임시 테이블 제안을 고려하거나 응용 프로그램 잠금 장치를 사용하여 다른 사람 이이 코드를 입력하는 것을 차단하십시오. 드롭/생성 거래는 원하는 것이 아닙니다.

다른 팁

왜 먼저이 일을하는지 물어봐도 될까요? 실제로 임시 테이블 사용을 고려하거나 다른 솔루션을 제시해야합니다.

DDL Statments가 트랜잭션에서 Sameway를 DML 문으로 행동하고 이상한 동작이있는 블로그 게시물을보고 DDL 내에서 저장된 절차를 작성하는 것이 긍정적이지 않습니다.

그로부터 트랜잭션 격리 수준을 확인하고 직렬화로 설정하려고 할 수 있습니다.

편집하다

빠른 테스트를 기반으로, 나는 두 개의 다른 연결에서 동일한 SQL을 실행했으며 테이블을 만들었지 만 거래를 커밋하지 않았을 때 두 번째 트랜잭션이 차단되었습니다. 이것이 작동하는 것처럼 보입니다. 나는 여전히 이러한 유형의 디자인에 대해주의를 기울일 것입니다.

이 과정 에서이 테이블을 사용하는 경우 온도 테이블을 사용하거나 데이터의 양에 따라 RAM 테이블을 사용하는 것이 좋습니다. 거래 비용을 피하고 디스크 활동을 절약하기 위해 RAM 테이블을 자주 사용합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top