2011-10-13 2 views
0

이 질문의 약간의 투기성에 대한 사과.메모리 내 이벤트 소싱 알고리즘 - 맞습니까? 그것은 threadsafe입니까?

시스템의 현재 상태를 유지하기 위해 메모리 내 정적 개체를 사용하여 Cms를 작성하고 이벤트 소싱을 사용하여 개체 상태를 다시 작성하고 롤백을 제공하는 데 사용할 수있는 이벤트 로그를 만듭니다. 등의 실행 또는 재 구축 시간이 오래 걸리는 경우 쌓아 쓰기의 많은의 가능성에서 제외

public class Cms 
{ 
    private static object WriteLock = new object(); 
    public static Cms Read { get; set; } 
    static Cms Write { get; set; } 

    static Cms() 
    { 
     Read = RebuildFromActionLog(); 
     Write = RebuildFromActionLog(); 
    } 

    public static void Update(Action action) 
    { 

     lock (WriteLock) 
     {     
      try 
      { 
       action.Apply(Write); 
      } 
      catch(Exception ex) 
      { 
       Write = RebuildFromActionLog(); //ditch the potentially messed up Write model 
       throw; 
      } 
      LogAction(action); //the action was a keeper, so keep it 
      Read = Write; //ditch the current read only model - it will continue to be used by any requests that have grabbed it 
      Write = RebuildFromActionLog(); //get a new model ready for the next write 
     } 
    } 
... 
} 

(더 내가 약에 누구인지 모를 경우 http://martinfowler.com/articles/lmax.html를 참조), 많은 메모리의 가능성 사용할 수있는 버그가 있습니까? 특히 동시성 관련 버그가 있습니까?

+0

starvetion 모드로 쓰레드가 없습니까? 잠금 장치 {} 블록을 사용하면 많은 시간이 걸리는 작업을 수행하지 않아야합니다. 또한, 하나의 스레드가 alock을 획득했고 해당 catch 블록이 예외를 발생시킨 경우이를 catch {} 블록에 던집니다. 그럼 자물쇠가 풀려날 것이라고 생각합니까 ?? – Zenwalker

+0

흠 어쩌면 이것은 동시 목록 또는 무언가로서 더 좋을 것이고, 그곳에 작업 큐를 올려 놓을 것입니다. 좋은 지적입니다! 나는 예외가 안전하다고 생각한다 : http://stackoverflow.com/questions/639493/in-c-how-can-i-safely-exit-a-lock-with-a-try-catch-block-inside – mcintyre321

+0

그는 잡기에서 던지고있다, 자물쇠는 결코 풀어 놓이지 않는다 나는 짐작한다. 내가 틀렸다면 나를 바로 잡습니다. 또한 스레드가 예외를 throw하면 응용 프로그램이 중단됩니다. – Zenwalker

답변

1

아무런 동기화가 없으므로 누군가가 공용 getter 또는 설정자인 Read을 사용하면 문제가 발생할 수 있습니다. 누군가 다른 스레드가 수정 한 것과 동시에 해당 특성을 사용하면 Update으로 읽음이 부실 값을 가져 오거나 쓰여진 변경 사항이 자동으로 없어 질 수 있습니다.

정말이 속성을 공개해야합니까? 공개적으로 쓰기 가능?

+0

def는 쓰기 불가능합니다. 비록 그것이 휘발성이어야하는지 궁금합니다. 앱의 나머지 부분이 공개되어 있어야 손에 넣을 수 있습니다. 맞습니까? 어쩌면 공공 getter와 함께 휘발성 개인 필드해야합니다 ... – mcintyre321

+0

@ mcintye321 : 만약 당신이 읽기/쓰기 다른 스레드에서 동기화하지 않고 다음 예 그것은 휘발성으로 표시되어야합니다 싶어요. 'volatile'에 대해서는 다음 문서를 참고하십시오 : http://msdn.microsoft.com/en-us/library/x13ttww7.aspx 그러나 '휘발성'이라 할지라도 여전히 원치 않는 경합 조건이 있습니다. –