2011-09-24 7 views
4

SQL Server와 같은 RDBMS를 사용하여 웹 응용 프로그램 프로그래밍 및 처리 동시 처리에 익숙하지 않습니다. SQL Server 2005 Express Edition을 사용하고 있습니다. 나는 동시 연결로 인해 발생할 수있는 문제를 처리하는 방법을 다음 있지 않다동시 환경에서 최대 처리량 (ID)

SELECT max(ID) FROM employees WHERE district = "XYZ"; 

:

나는 마지막 네 자리가이 쿼리에서 제공하는 직원 코드를 생성하고있다. 많은 사용자가 동일한 최대 (ID)를 선택할 수 있으며 한 사용자가 "레코드 저장"을 클릭하는 동안 다른 사용자가 이미 ID를 사용했을 수 있습니다.

이 문제를 어떻게 처리합니까?

+0

자동 증가 열을 사용하거나 한 번에 하나씩 만 실행되도록 쿼리를 트랜잭션으로 설정합니다. – Joe

+0

자동 증가. – RKh

+0

주어진 지구의 최대 ID를 가져 오시겠습니까? 그 신분증으로 뭐하니? ID 열은 ID 열입니까? 언제 쿼리를 실행합니까? 삽입 직후에 새로 생성 된 ID를 사용하고 싶습니까? –

답변

2

다음은 원하는 작업을 수행하는 두 가지 방법입니다. EmpCode에 대한 고유 한 제약 조건 위반으로 끝날 수도 있다는 사실에 대해 걱정할 필요가 없습니다 :).

1. 사용 scope_identity()는 마지막으로 삽입 된 ID를 얻을 EmpCode을 계산하는 것을 사용합니다.

표 정의 :

create table Employees 
(
    ID int identity primary key, 
    Created datetime not null default getdate(), 
    DistrictCode char(2) not null, 
    EmpCode char(10) not null default left(newid(), 10) unique 
) 

직원에 한 행을 추가합니다. 트랜잭션에서 수행되어야 하는가하면 EmpCodeleft(newid(), 10)에서 기본 임의의 값 왼쪽되지 않습니다 있는지 확인합니다 :

declare @ID int 

insert into Employees (DistrictCode) values ('AB') 

set @ID = scope_identity() 

update Employees 
set EmpCode = cast(year(Created) as char(4))+DistrictCode+right([email protected], 4) 
where ID = @ID 

2

computed column EmpCode을 확인합니다.

표 정의 :

create table Employees 
(
    ID int identity primary key, 
    Created datetime not null default getdate(), 
    DistrictCode char(2) not null, 
    EmpCode as cast(year(Created) as char(4))+DistrictCode+right(10000+ID, 4) unique 
) 

종업원에 하나 개의 행을 추가

insert into Employees (DistrictCode) values ('AB') 
1

Transaction Isolation Levels을 통해이를 수행 할 수 있습니다. 예를 들어, SERIALIZABLE을 레벨로 지정하면 다른 트랜잭션이 차단되어이 문제가 발생하지 않습니다.

귀하의 질문을 정확하게 이해하지 못했다면 알려주십시오.

2

을 삽입 할 수 없습니다 때문에 적절한 잠금 장치로, MAX 사용하는 것은 좋지 않다 같은 지구에있는 여러 스레드의 행 한 번에 한 명의 사용자 만 만들 수 있으며 지구마다 많은 사용자가있는 경우에도 MAX가 확장된다는 테스트 결과가 나온다면 사용해도 좋습니다. 간단히 말하면, 신분을 다루는 것은 가능하면 IDENTITY에 의지해야합니다. 정말.

그러나 가능하지 않은 경우 별도의 테이블에서 ID를 처리해야합니다.

Create Table DistrictID (
    DistrictCode char(2), 
    LastID Int, 
    Constraint PK_DistrictCode Primary Key Clustered (DistrictCode) 
); 

그런 다음 LastID 카운터를 증가시킵니다. 병렬 스레드에서 많은 사용자를 생성하려는 경우 ID를 증가시키는 것이 사용자 작성 트랜잭션으로 분리 된 트랜잭션이어야하는 것이 중요합니다. ID 생성 만 순서대로 수행하도록 제한 할 수 있습니다.

코드는 다음과 같을 수 있습니다

Create Procedure usp_GetNewId(@DistrictCode char(2), @NewId Int Output) 
As 

Set NoCount On; 
Set Transaction Isolation Level Repeatable Read; 
Begin Tran; 
Select @NewId = LastID From DistrictID With (XLock) Where DistrictCode = @DistrictCode; 
Update DistrictID Set LastID = LastID + 1 Where DistrictCode = @DistrictCode; 
Commit Tran; 

반복 읽기XLOCK 키워드는 동일한 ID를 얻기 위해 두 개의 스레드를 방지하는 데 필요한 최소 있습니다. 테이블이 모든 지구가없는 경우에는 직렬화반복 읽기을 변경해야하고, 삽입으로 업데이트 포크 것입니다.