2013-09-05 2 views
1

이것은 처음 stackoverflow에서 묻는 것입니다 :) 나는 중간 규모의 winforms 응용 프로그램을 C#에서 SQL Server 2008에 연결하여 개발 한이 응용 프로그램은 비즈니스를위한 것입니다. 관리 앱 (중견 기업용)의 경우 견적, 인보이스 등을 만들 수 있습니다.때로는 내 새로운 데이터가 SQL 서버의 이전 데이터를 대체합니다

포인트 종종 (항상은 아님) 한 컴퓨터에서 한 사용자가 해당 업체가 SQL 저장 얻을 견적을 생성하고, 그 결과로서 ID를 수신한다. 나서, 동시에 서로 다른 컴퓨터에서 다른 사용자가 다른 제품 견적을 작성하고, 동일한 ID를 수신하고, 결과로서 마지막 견적 첫번째 중첩.

이 매우 자주 발생하지 않지만, 일, 그리고 아마도 가장 좋은 방법은 데이터의 개별화를 보장하는 것입니다 이유를 찾을 수없고, 너희들 중 일부는 좀 빛을 가져올 수 있습니다.

사실은 다음과 같습니다 그것은 항상이 정확한 사람 (우리가 6 개 영업 사원이 있고이 문제가 항상 같은이 영업 사원으로 발생하는) 사람이 원격으로 너무 원격 데스크톱을 사용하여 내 애플 리케이션에 노력하고 그 매출의 하나 일어날 , 해당 응용 프로그램의 인스턴스가 서버에서 실행 중입니다. 다른 판매원이 서버가 설치된 동일한 네트워크의 자체 컴퓨터에서 응용 프로그램을 로컬로 사용하고 있습니다. 당신은 다음과 같은 3 개 테이블을 찾을 수

데이터베이스 구조에서

: 다음과 같이

데이터를 저장하기위한 과정입니다 1) 견적 2) 견적의 "세부 사항"의 "데이터 헤더" 3)보고 문제와 관련된 견적의 테이블 세부 정보

1) 견적을 만들고 "수락"버튼을 누르면 앱에서 "데이터 헤더"를 가져 와서 저장합니다. 다시 ID를 다시 ID로 2) (안 데이터베이스의 ID 그러나 ID는 일부 회사 정책에 유래), 앱이 "D를 저장하기 시작 etail " 3) 사용자가 견적을 인쇄하려면 보고서가 생성되고 세부 정보 테이블의 세부 정보 데이터가 보고서 테이블에 일시적으로 복사됩니다.

오류가 발생하면 , 나는 데이터베이스를 쿼리하고 단 하나의 견적 (마지막 하나)이 등록되어 있으므로, 마지막 견적이 첫 번째 견적과 겹치는 것을 이해합니다.

처음에는 SQL에서 반환하는 ID를 생성하는 방식과 관련된 문제가 발생할 수 있습니다. 실제로 작성하는 방식은 실제로 매우 간단합니다. - 견적의 ID를 작성하고 등록하기 위해 할당 된 마지막 번호를 확인합니다. 더하기 하나 - 숫자가없는 경우 (테이블의 첫 번째 데이터) 초기 ID로 하나만 지정합니다.

왜 테이블 키를 ID로 사용하지 않습니까? 시스템이 다른 시스템과 comunicate 수 필요가 있고 그들이 ID를 생성 저장 프로 시저에서 ID의

코드의 범위에서 specifical ID의의를 필요로하기 때문에 다음과 같은 : 그래서

BEGIN TRAN 
DECLARE @newNumDoc INT 
SET @newNumDoc = (ISNULL((SELECT MAX(NUMDOC) FROM REMISION_DBF WHERE idEmpresa = @idEmpresa),0) + 1) 
IF @newNumDoc IS NULL 
    SET @newNumDoc = 1 
COMMIT TRAN 

, 누군가가 나를 도울 수 중첩 된 데이터가 누락되지 않도록하기 위해 문제의 위치를 ​​파악하거나 최소한 중점을 변경해야합니다.

+0

당신이 IDENTITY 열을 사용하는 경우, 이것은 일어나지 않을 것이다. –

답변

0

문제는 실제로 그 안에 있어야합니다 코드는 트랜잭션을 처리하고있는 방식이며,.귀하의 트랜잭션이 현재 다음 SQL 다룹니다

  • 이 널 (null)의 경우, 설정 1

그러나에 데이터베이스 테이블에서 가장 높은 NUMDOC 값을 가져 오기를, 이건 정말 아니다 어떤 시점에서 다른 레코드를 삽입하기 때문에 트랜잭션에 적합한 트랜잭션입니다. 다른 프로세스가 계속해서 정확히 동일한 숫자를 얻을 수없는 이유는 없습니다. 실제로, 이것이 여러분이보고있는 것입니다. 당신이해야 할 일은

는 다음의 라인을 따라 더 :

BEGIN TRAN 
DECLARE @newNumDoc INT 
SET @newNumDoc = (ISNULL((SELECT MAX(NUMDOC) FROM REMISION_DBF WHERE idEmpresa = @idEmpresa),0) + 1) 
IF @newNumDoc IS NULL SET @newNumDoc = 1 
INSERT INTO REMISION_DBF (NUMDOC) VALUES (@newNumbDoc) 
COMMIT TRAN 

이 당신의 NUMDOC가 현재 프로세스를 위해 예약되어 있는지 확인 것이고, 그것은 단순히 전환 데이터를 쓰기에 관해서 다음 때 귀하의 현재 INSERTUPDATE입니다.

(이것은 분명히 별도로 해결 필요가 사용자의 시스템에 다른 문제를 제기 할 수 있지만, 당신도 NUMDOC 값의 고유성을 보장하는 출발점을 줄 것이다 물론

, 대안은있다,. 예를 들어, 하나 가능성은 REMISION_DBF의 오염을 방지하기 위해 "예약"의 별도의 테이블을 사용하는 것입니다. 그러나 그렇다하더라도, 같은 BEGIN TRAN ... GET ... INSERT ... COMMIT 모델이 적용됩니다.)

관련 문제