2011-08-28 6 views
5

다음은 웹 응용 프로그램에서 수행하고자하는 두 가지 잠재적 인 워크 플로입니다.웹 애플리케이션에서 동시 변경 사항을 처리하려면 어떻게해야합니까?

바리에이션 1

  • 사용자
  • 서버
  • 서버
  • 서버 데이터

2 변형 수정 세이브 데이터를 수정 데이터를 판독 요청을 보낸다

  • 사용자는
  • 서버가
  • 서버가
  • 사용자가
  • 서버가 데이터를 각각의 경우에

을 수정 저장합니다, 나는 궁금 수정을 요청을 보내는 사용자에게 데이터를 전송 데이터를 읽어 요청 보냅니다 이 서비스에 대한 동시 액세스로 정상적인 결과가 나오는지 확인하기위한 표준 접근 방식은 무엇입니까?

상황은 가상이다 (누구의 편집이 사방됩니다 즉, 값 등 편집의 어떤 순서에 해당),하지만 여기에 내가 실제로이 처리해야 할 가능성이 것 곳의 몇 가지 세부 사항은 다음과 같습니다

  • 웹 응용 프로그램,하지만
  • 잠재적으로 지정되지 않은 언어는 웹 프레임 워크를 사용하여
  • 데이터 저장소는 SQL 관계형 데이터베이스에게 있습니다
  • 관련된 로직은 쿼리의 예에서 잘 표현하기 위해 너무 복잡 value = value +1 1

휠을 다시 시도하지 않으려는 것처럼 느껴집니다. 분명히 잘 알려진 해결책으로 잘 알려진 문제입니다. 제발 조언.

감사합니다.

답변

4

가장 잘 알고있는 한,이 문제에 대한 일반적인 해결책은 없습니다.

근본적인 문제는 사용자가 업데이트를 저장하기 전에 오랜 시간 동안 데이터를 검색하여 화면에서 응시 할 수 있다는 것입니다.

  1. 사용자가 데이터베이스를 읽고, 기록을 잠금, 사용자가 업데이트를 절약 할 때까지 공개하지 않습니다

    나는 세 가지 기본 방법을 알고. 실제로 이것은 비현실적입니다. 사용자가 화면을 가져 와서 저장하지 않고 점심을 먹으면 어떻게 될까요? 아니면 오늘 집에 간다? 아니면 그가 끝내고 결코 돌아 오지 않는이 어리석은 기록을 업데이트하려고 너무 좌절 했나요?

  2. 목적지를 업데이트하지 않고 델타로 업데이트하십시오. 고전적인 예를 들어 재고를 재고로 기록하는 시스템이 있다고 가정합니다. 매매가있을 때마다 재고 조사 수에서 1을 (또는 그 이상) 빼야합니다.

따라서 현재 수량은 10입니다. 사용자 A가 판매를 생성합니다. 현재 수량 = 10. 사용자 B가 판매를 생성합니다. 또한 현재 수량 = 10을 얻습니다. 사용자 A는 두 개의 단위가 판매됨을 입력합니다. 새 수량 = 10 - 2 = 8. 저장하십시오. 사용자 B는 하나의 단위로 판매됩니다. 새 수량 = 10 (로드 한 값) - 1 = 9. 저장하십시오. 분명히 뭔가 잘못되었습니다.

해결 방법 : "업데이트 인벤토리 세트 수량 = 9, 여기서 itemid = 12345"대신 "업데이트 인벤토리 세트 수량 = 수량 -1 여기서 itemid = 12345"라고 씁니다. 그런 다음 데이터베이스가 업데이트 큐에 대기하게하십시오. 전략 # 1과 매우 다르다. 데이터베이스가 레코드를 읽고 수정하고 기록하기 만하면된다. 누군가가 화면을 보면서 기다릴 필요가 없습니다.

물론 이것은 델타로 표시 될 수있는 변경에만 사용할 수 있습니다. 고객의 전화 번호를 업데이트하는 경우 작동하지 않습니다. (예전의 전화 번호는 555-1234입니다. 사용자 A는 555-1235로 바꾸라고 말합니다. +1의 변경입니다. 사용자 B는 555-1243으로 바꾸라고 말합니다. 이것은 +9의 변경입니다. +10, 고객의 새 번호는 555-1244입니다. :-))하지만 그런 경우 "Enter 키를 누르는 마지막 사용자"가 아마도 어쨌든 할 수있는 최선입니다.

  1. 업데이트시 데이터베이스의 관련 필드가 "from"값과 일치하는지 확인하십시오. 예를 들어, 귀하의 고객을위한 계약을 협상하는 법률 회사에서 일한다고 가정 해보십시오. 사용자가 협상에 대한 메모를 입력 할 수있는 화면이 있습니다. 사용자 A가 계약 레코드를 표시합니다. 사용자 B는 동일한 계약 레코드를 가져옵니다. 사용자 A는 전화로 상대방에게 방금 말했고 제안 된 조건에 동의합니다. 또한 상대방에게 전화를 시도한 사용자 B는 자신이 전화에 응답하지 않고 자신이 돌발적으로 의심하고 있다고 진술합니다. 사용자 A가 저장을 클릭합니다. 사용자 B의 댓글로 사용자 A를 덮어 쓰게할까요? 아마도 그렇지 않습니다. 대신 레코드를 읽은 후에 노트가 변경되었음을 나타내는 메시지를 표시하고 저장을 진행할지, 중단할지 또는 다른 것을 입력 할지를 결정하기 전에 새 값을 볼 수 있도록 허용합니다.

[참고 : 포럼은 자동으로 번호가 매겨진 목록의 번호를 다시 매겨집니다. 이것을 덮어 쓰는 방법을 잘 모르겠습니다.]

0

모든 요청은 다른 스레드 (또는 프로세스)가 제공하므로 모든 처리 클래스 (서비스)에 상태가 없으면 모든 것이 안전합니다.

데이터베이스에 도달하면 상황이 더 복잡해집니다 (즉, 상태가 유지되는 위치). 모든 항목이 정상적으로 작동하려면 transactions이 필요합니다.

트랜잭션에는 "데이터베이스 트랜잭션이 안정적으로 처리되도록 보장하는"속성 집합 인 ACID이 있습니다.

+0

감사합니다. 변형 1에 대해서는 정상적으로 작동합니다.하지만 트랜잭션이없는 상황에서이 문제를 처리하는 일반적인 방법은 무엇입니까? 예 :MySQL의 MyISAM – Ming

+0

명확히하기 위해, 많은 포럼 소프트웨어가 이러한 종류의 문제를 처리해야한다고 생각합니다. 그러나 많은 사람들이 트랜잭션이없는 MyISAM을 사용합니다. 이것에 대한 해결책은 무엇입니까? – Ming

+0

안정적으로 처리 할 수 ​​없습니다. 포럼 소프트웨어는 주로 삽입에 의존하며 동시 편집은 거의하지 않으므로 많은 문제가 발생하지는 않습니다. – Bozho

0

mysql에 트랜잭션이 없으면 update 명령을 사용하여 데이터가 손상되지 않았는지 확인할 수 있습니다.

UPDATE tableA SET status=2 WHERE status = 1 

상태가 1이면 하나의 프로세스 만 레코드가 업데이트 된 결과를 얻습니다. 아래 코드에서 업데이트가 실행되지 않으면 -1을 반환합니다 (업데이트 할 행이없는 경우).

PreparedStatement query; 
query = connection.prepareStatement(s); 
int rows = -1; 
try 
{ 
    rows = query.executeUpdate(); 
    query.close(); 
} 
catch (Exception e) 
{ 
    e.printStackTrace(); 
} 
return rows; 
관련 문제