2017-12-08 3 views
0

여기에 바나나가 있습니다. 동시성 보호를 구현하려고 시도했습니다.동시성 보호가 작동하지 않습니다.

그래서 두 가지 방법이 있습니다. Optimistic - 기본적으로 레코드에 버전 필드를 추가하면 각 저장에서 버전 필드가 증가합니다. 따라서 현재 버전 필드가 디스크의 내용과 다르면 수정 된 내용을 의미하며 오류가 발생합니다.

비관적 인 접근 방식은 레코드를 잠그는 것이며 편집 할 수 없음을 의미합니다.

Django 용 양방향 동시성 패키지를 구현했으며 SQLLite와 Heroku가있는 Postgres에서 아무것도 작동하지 않습니다. 다음은

그것이이 모두 비관적에 대한

접근 내보기 방법, 난 select_for_update 를 사용하여 원자 트랜잭션과 잠금 내가 동시성 장고 패키지를 사용 낙관적 각 편집에 내 버전 필드를 증가 그와 간단한 비교를 on_disc 값

내가 뭘 잘못 했니? 도와주세요?

@login_required 
    def lease_edit(request,pk,uri): 
     logger = logging.getLogger(__name__) 
     title = 'Edit Lease' 
     uri = _get_redirect_url(request, uri) 


     with transaction.atomic(): 

      post = get_object_or_404(Lease.objects.select_for_update(), pk=pk) 

      if request.method == "POST": 
       form = LeaseForm(request.POST, instance=post) 
       if form.is_valid(): 
        lease = form.save(commit=False) 
        on_disc= Lease.objects.get(pk=post.id) 
        if on_disc.version > post.version: 
         messages.add_message(request, messages.ERROR, str(lease.id) + "-Error object was modified by another user. Please reopen object.") 
         return redirect(uri) 


        lease.save() 
        messages.add_message(request, messages.SUCCESS, str(lease.id) + "--SUCCESS Object saved successfully") 
        return redirect(uri) 
      else: 
       form = LeaseForm(instance=post) 
      #lease = post.lease 
      return render(request, 'object_edit.html', {'form': form, 'title':title, 'extend': EXTEND}) 

는 동일한 레코드와 I를 열어 2 브라우저를 테스트하고 모두 병렬로

+0

편집하는 동안 서버에서 코드가 실행되고 있지 않으므로 트랜잭션이 사용자가 아무것도 편집하지 못하도록 기다리지 않습니다.매우 자연스럽게 업데이트하는 동안 만 활성화되며, 매우 운이 좋으면서 동시에 두 가지 요청을 실행하지 않는 한 잠금을 고정, 업데이트 및 해제하는 데 오류가 발생하지 않습니다. 디스크 버전 번호 확인 작업에 대해서는 정확히 이유를 말할 수 없습니다. 코드가 브라우저에서 ID를 받거나 POST에서 데이터베이스에서 읽는 것처럼 보입니까? –

+0

낙관적 인 경우 다른 질문에 대한 의견을 받았습니다 .https : //stackoverflow.com/questions/47692858/data-is-not-being-read-directly-from-the-database-instead-of-buffer-on -2nd-call "데이터베이스 자체가 다른 트랜잭션에서 항목을 잠그고 있지만 트랜잭션 격리 설정으로 인해이 프로세스가 업데이트 된 값을 볼 수 없습니다."하지만 처리 방법을 모릅니다. –

+0

하지만 코드를 올바르게 읽어야합니까? select를 사용하여 데이터베이스에서'post'를 얻은 다음 저장하고'on_disc'를 얻고 비교합니까? 이들 중 어느 것도 * previous * 값을 가진 * previous * 요청에 속하지 않기 때문입니다. 이 둘은 * this * 요청에서 왔으며 항상 일치합니다. 값을 브라우저에 보내고 값을 가져 와서 현재 값과 비교해야합니다. –

답변

0

문제는 웹 사이트가 작동하는 방법을 함께 (나는 동일한 사용자를 사용) 편집하려고합니다. 현재 당신의 잠금은 다음과 같이 작동

  • GET 요청 데이터를로드 당신은 행, 부하를 고정
    • ,
  • 브라우저
  • POST에 데이터를 편집, 브라우저에 보내는 잠금을 해제 데이터를 서버에 전송
    • 행을 잠그고 업데이트, 잠금 해제

행을 잠근 상태로 유지하는 것은 여기에 없습니다. 각 요청 후에 행이 잠금 해제되므로 여러 인스턴스가 서버로 데이터를 보낼 수 있습니다. 이것은 웹 시스템이 일반적으로 작동하는 방식이며, 각 요청은 분리되어 있으며 잠금은 다르게 수행되어야합니다.

행 버전 관리에 대해서는 코드를 올바르게 이해하면 현재 행 번호가 브라우저로 전송되지 않지만 업데이트하는 동안 읽게됩니다. 이것은 다시 올바른 번호를 얻는다는 것을 의미합니다. 브라우저에 현재 번호를 보내고 POST에서 해당 번호를 데이터베이스의 현재 번호와 비교해야합니다. 이렇게하면 무언가가 바뀌면 감지합니다.

장고에 익숙하지 않아서이 부분에 대해서는 틀릴 수도 있지만 코드의 기능을 이해하고 있습니다. 나는 form에 현재 행 버전이 있다고 가정하지만 데이터베이스와 현재의 숫자 만 비교하지는 않습니다 (가능하면 숫자가 변경 될 수도 있음).

+0

아직 작동하게하십시오. 이후 양식에서 버전을 얻는 데 문제가 있습니다. 그러나 나는 당신이 맞았다 고 생각합니다. 고맙습니다 –

관련 문제