저자www.itsvse.com @小渣渣 ! 기본 데이터를 성공적으로 삽입하세요! ConcurrencyCheck 기능 테스트가 완료되었습니다 업데이트 성공! 주석 1 업데이트는 정말 대단합니다! 참고 2, 비정상적인 정보! 업데이트, 삽입, 삭제 저장 문이 예상치 못한 수의 행(0)에 영향을 미쳤습니다. 엔티티가 로드된 이후에 수정되거나 삭제되었을 수 있습니다. 긍정적 동시성 예외를 이해하고 처리하는 방법에 대한 정보는 http://go.microsoft.com/fwlink/?LinkId=472540 를 참조하세요.
타임스탬프와 동시성 확인(ConcurrencyCheck)의 차이 테스트 업데이트Tab1 업데이트 성공! 이름 1 업데이트Tab2 업데이트 성공! 이름 1 UpdateTab2 업데이트가 비정상적이에요! 이름 2, 비정상 정보! 업데이트, 삽입, 삭제 저장 문이 예상치 못한 수의 행(0)에 영향을 미쳤습니다. 엔티티가 로드된 이후에 수정되거나 삭제되었을 수 있습니다. 긍정적 동시성 예외를 이해하고 처리하는 방법에 대한 정보는 http://go.microsoft.com/fwlink/?LinkId=472540 를 참조하세요. 업데이트Tab1 업데이트 성공! 이름 2
【타임스탬프】 TimeStamp 기능은 바이트 배열 속성이 하나뿐인 필드 클래스에 적용할 수 있으며, 이 기능은 tiemStamp 타입을 열로 설정합니다. 동시 검사에서 Code-First는 자동으로 이 타임스탬프 유형 필드를 사용합니다.
【동시성 확인] ConcurrencyCheck 기능은 도메인 클래스의 속성에 적용할 수 있습니다. EF가 업데이트 작업을 수행할 때, Code-First는 해당 열의 값을 where 조건 문에 입력하며, 이 CurrencyCheck 기능을 사용해 별도의 타임스탬프 열을 동시성 검사에 사용할 수 있습니다.
우선 동시성 처리에서 Timestamp와 ConcurrencyCheck의 차이를 보여주기 위해 새로운 컨텍스트 객체를 만들어 보겠습니다!
맥락을 위한 코드는 다음과 같습니다:
데이터베이스의 열들을 다음과 같이 살펴보겠습니다:
tab1과 tab2는 Id, Name, Remark 열을 가지고 있고, tab2는 tab1보다 RowVersion 열이 더 많다는 것을 알게 됩니다.
먼저 테스트 코드를 첨부하세요:
【동시성 확인 원칙】
우리는 Tab1의 Remark 속성에 ConcurrencyCheck 기능을 추가했습니다.
같은 데이터의 Name 속성 값을 동시에 업데이트해도 예외가 발생하지 않습니다!
SQL 문 생성:
N'UPDATE sp_executesql [dbo]의 임원. [탭1] SET [이름] = @0 여기서 ([Id] = @1) AND ([주석] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name1',@1=1,@2=N'Note1' N'UPDATE sp_executesql [dbo]의 임원. [탭1] SET [이름] = @0 여기서 ([Id] = @1) AND ([주석] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name2',@1=1,@2=N'note1' 같은 데이터의 Remark 속성 값을 동시에 업데이트하면 예외를 던집니다!
SQL 문 생성:
N'UPDATE sp_executesql [dbo]의 임원. [탭1] SET [주석] = @0 여기서 ([Id] = @1) AND ([주석] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note1',@1=1,@2=N'Note' N'UPDATE sp_executesql [dbo]의 임원. [탭1] SET [주석] = @0 여기서 ([Id] = @1) AND ([주석] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note 2',@1=1,@2=N'Note' 동일한 데이터 조각을 Id 1로 동시에 취하면 Remark 속성의 값을 얻고, Remark 속성을 업데이트할 때 Remark 속성을 업데이트 조건으로 사용합니다.
첫 번째 SQL 문장은 성공적으로 업데이트될 수 있고, 그 후 주석은 "note 1"로 변경되며, 두 번째 SQL 문장이 업데이트되면 주석 값이 변경되어 업데이트가 실패합니다.
【타임스탬프 원리】
Tab2에 RowVersion 속성을 추가했고(어떤 이름이든 사용할 수 있음), 타임스탬프 기능도 추가했습니다!!
같은 데이터의 이름 값을 동시에 업데이트하면 첫 번째 업데이트는 성공하고 두 번째 업데이트는 실패하며 예외가 발생하는데, 생성된 SQL 코드를 살펴보겠습니다!
N'UPDATE sp_executesql [dbo]의 임원. [탭2] SET [이름] = @0 여기서 (([Id] = @1) AND ([RowVersion] = @2)) AND ([주석] = @3)) 선택하세요 [RowVersion] [dbo]에서 왔습니다. [탭2] 여기서 @@ROWCOUNT > 0 AND [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'Name1',@1=1,@2=0x00000000000007D1,@3=N'Note' N'UPDATE sp_executesql [dbo]의 임원. [탭2] SET [이름] = @0 여기서 (([Id] = @1) AND ([RowVersion] = @2)) AND ([주석] = @3)) 선택하세요 [RowVersion] [dbo]에서 왔습니다. [탭2] 여기서 @@ROWCOUNT > 0 AND [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'name2',@1=1,@2=0x00000000000007D1,@3=N'Note' 두 번째 SQL 문장을 실행할 때, where 조건의 데이터를 더 이상 찾을 수 없기 때문에 업데이트가 실패하고 예외가 던져집니다!!
첫 번째 SQL 문이 성공적으로 실행되면 RowVersion의 값이 바뀌며, 아래 그림과 같이 나타납니다:
RowsVersion은 타임스탬프입니다
누락된 업데이트 우회 방법
누락된 업데이트 개념: 사용자가 동시에 데이터 한 줄을 수정할 때, 먼저 데이터를 읽고 프론트엔드에 올리고 수정한 후 데이터를 제출하여 최종 제출된 데이터가 이전에 제출된 데이터를 덮어쓰게 하여 업데이트가 손실됩니다.
간단히 말해, 업데이트 손실을 방지하는 방법은 다음과 같습니다:
RowsVersion 타임스탬프를 사용하세요.
읽기 전에 행이 값과 일치하지 않는다면, 다른 트랜잭션이 이 열을 업데이트했으므로 이 열을 업데이트할 수 없게 하여 업데이트 손실을 방지합니다.
마지막으로 소스 코드를 첨부하세요:
CodeFirstDemo.rar
(4.94 KB, 다운로드 횟수: 13)
|