asp.net core 시리즈 의 병발 충돌 에 대한 깊 은 이해

본 고 는 여러 사용자 가 같은 실 체 를 동시에 업데이트 할 때 발생 하 는 충돌 을 어떻게 처리 하 는 지 소개 한다.
주로 두 가지 입 니 다.하 나 는 속성 과 충돌 을 검사 하고[Concurrency Check]을 사용 합 니 다.다른 하 나 는 줄 의 동시 충돌 을 감지 하고 rowversion 추적 속성 을 사용 합 니 다.저장 하기 전에 수정 이 있 으 면 오류 가 발생 합 니 다.
동시 충돌 이 발생 한 경우:
1.사용자 가 실체 편집 페이지 로 탐색 하기;
2.첫 번 째 사용자 의 변경 사항 이 데이터베이스 에 기록 되 기 전에 다른 사용자 가 같은 실 체 를 업데이트 합 니 다.
이 때 병렬 검 사 를 사용 하지 않 으 면 업데이트 가 발생 할 때:
마지막 업데이트 우선.마지막 업데이트 값 을 데이터베이스 에 저장 하 는 것 입 니 다.첫 번 째 저장 값 은 분 실 됩 니 다.
예 를 들 어:
1.제 인 은 학과 편집 페이지 를 방문 하여 영문 과 예산 을 350,000.00 달러 에서 0.00 달러 로 변경(첫 번 째 사용 자 는 금액 을 0 으로 변경)

2.Jane 이'저장'을 누 르 기 전에 John 은 같은 페이지 를 방문 하고 시작 날짜 필드 를 2007/1/9 에서 2013/1/9 로 변경 합 니 다.(첫 번 째 사용자 가 저장 하기 전에 두 번 째 사용 자 는 시간 을 07 년 에서 13 년 으로 바 꾸 었 습 니 다.이때 두 번 째 사용자 가 본 금액 은 0 이 아 닙 니 다)

3.Jane 은'저장'을 누 르 고 브 라 우 저 에서 색인 페이지 를 표시 할 때 변경 사항 을 봅 니 다.(첫 번 째 사용자 가 먼저 저장 하고 브 라 우 저 에서 그의 수정 을 볼 수 있 습 니 다.금액 이 0 으로 변 하고 시간 이 변 하지 않 습 니 다)

4.John 은'편집'페이지 의'저장'을 누 르 지만 페이지 의 예산 은 350,000.00 달러 로 표 시 됩 니 다.(두 번 째 사용자 가 저장 합 니 다.이 페이지 의 예산 은 350000 달러 미 만 이 고 시간 은 13 년 입 니 다)
사실 이 결 과 는 병발 충돌 의 처리 방식 에 달 려 있다.
우선 이것 은 낙관적 인 병발 충돌 이 라 고 성명 한다.그렇다면 낙관적 인 병발 충돌 은 무엇 일 까?
낙관적 인 병발 충돌 은 병발 충돌 을 허용 하고 병발 충돌 이 발생 할 때 정확 한 반영 을 한다.
이렇게 많은 말 을 했 으 니,동시에 충돌 하 는 처리 방식 은?
1.사용자 가 수정 한 속성 을 추적 하고 데이터베이스 에 있 는 열 만 업데이트 할 수 있 습 니 다.
이렇게 하면 두 사용자 가 서로 다른 속성 을 업데이트 하면 다음 에 볼 때 모두 유효 합 니 다.
그러나 이런 방법 에 도 문제 가 있다.
4.567917.같은 속성 을 경쟁 적 으로 변경 하면 데이터 손실 을 피 할 수 없습니다4.567917.보통 웹 응용 에 적용 되 지 않 습 니 다.모든 추출 값 과 새 값 을 추적 할 수 있 도록 중요 한 상 태 를 유지 해 야 합 니 다.대량의 상 태 를 유지 하면 응용 성능 에 영향 을 줄 수 있다4.567917.응용 복잡성 을 증가 시 킬 수 있다(실체 적 인 병행 검 측 에 비해).
예 를 들 어 다음 에 영어 과 를 방문 하 는 사람 이 있 을 때 제 인과 존 두 사람의 변경 사항 을 볼 수 있다 는 것 이다.
2.클 라 이언 트 우선 순위
즉,클 라 이언 트 의 값 이 데이터베이스 에 저 장 된 값 보다 낫다.또한 동시 처리 에 어떠한 인 코딩 도 하지 않 으 면 클 라 이언 트 우선 순위 가 자동 으로 진 행 됩 니 다.
즉,John 의 변경 사항 은 Jane 의 변경 사항 을 덮어 씁 니 다.다음 에 영어 과 를 방문 할 때 2013/9/1 과 추출 한 값 350,000.00 달러 를 볼 수 있다 는 것 이다.
3.저장 우선
이런 방식 은 데이터베이스 에서 John 의 변경 을 막 을 수 있다.그리고
오류 메시지 표시
데이터 의 현재 상 태 를 표시 합 니 다4.567917.사용자 가 변경 사항 을 다시 적용 할 수 있 도록 합 니 다.
처리 병발
속성 이 병발 토 큰 으로 설정 되 었 을 때: 
데이터베이스 와 데이터 모델 은 DbUpdateConcurrency Exception 을 지원 하 는 것 으로 설정 해 야 합 니 다.
속성 병렬 충돌 검출
Concurrency Check 기능 을 사용 하여 속성 단계 에서 충돌 을 감지 할 수 있 습 니 다.이 기능 은 모델 의 여러 속성 에 적용 할 수 있 습 니 다.[Concurrency Check]특성
검사 줄 의 병렬 충돌
동시 충돌 을 감지 하려 면 rowversion 추적 열 을 모델 에 추가 하 십시오.
메모:rowversion,
1.SQL Server 가 지정 한 것 입 니 다.다른 데이터 베 이 스 는 유사 한 기능 을 제공 할 수 없 을 수도 있다.
2.데이터베이스 에서 실 체 를 추출 한 후 실 체 를 변경 하지 않 았 는 지 확인 하 는 데 사용 합 니 다.
데이터 베 이 스 는 rowversion 번 호 를 생 성 합 니 다.이 숫자 는 줄 마다 업데이트 되면 서 점점 증가 합 니 다.
update 나 delete 명령 에 where 자구 에는 rowversion 추출 값 의 판단 이 포함 되 어 있 습 니 다.
업데이트 할 줄 이 수정 되 었 다 면 rowversion 추출 값 은 현재 데이터베이스 에 있 는 rowversion 값 과 일치 하지 않 습 니 다.
update 나 delete 명령 에서 줄 을 찾 을 수 없습니다.DbUpdateConcurrency Exception 이상 유발
예시
Department 실체 에 추적 속성 추가

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
public class Department
{
public int DepartmentID { get; set; }
[StringLength(50, MinimumLength = 3)]
public string Name { get; set; }
[DataType(DataType.Currency)]
[Column(TypeName = "money")]
public decimal Budget { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Start Date")]
public DateTime StartDate { get; set; }
public int? InstructorID { get; set; }

[Timestamp]
public byte[] RowVersion { get; set; } //    

public Instructor Administrator { get; set; }
public ICollection<Course> Courses { get; set; }
}
}
Timestamp 기능 은 이 열 을 update 와 delete 명령 의 where 자구 에 포함 시 킵 니 다.
Fluent API 로 추적 속성 을 지정 할 수도 있 습 니 다.

modelBuilder.Entity<Department>()
.Property<byte[]>("RowVersion")
.IsRowVersion();
Department 이름 을 업데이트 할 때 EF Core 에서 생 성 된 부분 T-SQL 을 보 여 줍 니 다.

SET NOCOUNT ON;

UPDATE [Department] SET [Name] = @p0
WHERE [DepartmentID] = @p1 AND [RowVersion] = @p2;

SELECT [RowVersion]
FROM [Department]
WHERE @@ROWCOUNT = 1 AND [DepartmentID] = @p1;
앞의 코드 는 RowVersion 을 포함 하 는 WHERE 자 구 를 표시 합 니 다.데이터베이스 RowVersion 이 RowVersion 인자 와 같 지 않 으 면(@p2
),줄 을 업데이트 하지 않 습 니 다.
@@ROWCOUNT 는 이전 문장의 영향 을 받 은 줄 수 를 되 돌려 줍 니 다.줄 업데이트 없 이 EF Core 가
DbUpdateConcurrencyException
이 글 은 주로 자신의 기록 학습 을 편리 하 게 하기 위해 서 입 니 다.만약 잘못 이 있 으 면 지적 을 환영 합 니 다.
여기에 참고 자 료 를 동봉 합 니 다.
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/concurrency?view=aspnetcore-2.2&tabs=visual-studio
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
  • EF Core 는 추출 속성 을 검증 한 후 속성 을 변경 하지 않 았 는 지 확인 합 니 다.SaveChanges 나 SaveChangesAsync 를 호출 할 때 이 검 사 를 수행 합 니 다.
  • 속성 을 추출 한 후 속성 을 변경 하면 DbUpdateConcurrency Exception 이 발생 합 니 다.
  • 좋은 웹페이지 즐겨찾기