2016-06-05 7 views
1

사전 조건이 적용되는 분산 OLTP 상황에 대한 알려진 아키텍처 솔루션이 있습니까? 예를 들어, 은행 예제를 사용합시다. 사람 A는 $ N을 사람 B에게 이전하려고합니다.이 성공을위한 사전 조건은 사람 A가 자신의 계정에 $ N 이상을 가져야한다는 것입니다.고 분산 OLTP 아키텍처

사람 A의 관점에서 볼 때, 그들은 웹 애플리케이션에 로그인합니다. 그들은 $ N을 위해 그들 자신으로부터 사람 B에게 이전을 만든다. 백그라운드에서이 송금이 적용되고 송금이 생성 될 때 돈이 인출되어 A 사의 계좌에서 실시간으로 입금됩니다. 돈은 창작 전에 존재할 수 있지만, 일단 송금이 ​​적용되면 돈이되지 않을 수 있습니다. 즉, 이것이 클라이언트 측 검증 일 수는 없습니다. 사람 A는이 전송이 동 기적으로 성공했는지 실패했는지 알고 싶습니다. 사람 A는 전송을 비동기 적으로 제출 한 다음 나중에 대기열로 보내거나 전송에 실패했다는 알림을 보내지 않습니다.

이 문제를 대규모로 해결하는 알려진 아키텍처가 있습니까? 모든 계정이 단일 RDBMS에 있으면 내장 된 트랜잭션 기능을 통해 이와 같은 작업을 수행 할 수 있습니다. 그러나 궁극적으로 일관된 NoSQL 스타일 데이터 저장소 나 Kafka와 같은 로그/메시지 기반 인프라를 사용하고 있다면 이와 같은 문제에 대한 알려진 해결책이 있습니까?

+0

접근 방식이나 도구가 필요한지 확실하지 않지만 다음을 참고하십시오. http://blog.cask.co/2014/11/how-we-built-it-designing-a-globally- 일관된 트랜잭션 엔진 / – guillaume31

답변

0

기본적으로 분산 잠금 메커니즘이 필요합니다. 많은 분산 서버 응용 프로그램이 이러한 기능을 제공합니다. 우리가 코드에 질문을 변환 기본적으로 경우이

// BANK WITHDRAWAL APPLICATION 

// Fetch BankAccount object from NCache 
BankAccount account = cache.Get("Key") as BankAccount; // balance = 30,000 
Money withdrawAmount = 15000; 

if (account != null && account.IsActive) 
{ 
    // Withdraw money and reduce the balance 
    account.Balance -= withdrawAmount; 

    // Update cache with new balance = 15,000 
    cache.Insert("Key", account); 
} 

=========================

처럼

볼 것이다

// BANK DEPOSIT APPLICATION 

// Fetch BankAccount object from NCache 
BankAccount account = cache.Get("Key") as BankAccount; // balance = 30,000 
Money depositAmount = 5000; 

if (account != null && account.IsActive) 
{ 
    // Deposit money and increment the balance 
    account.Balance += depositAmount; 

    // Update cache with new balance = 35,000 
    cache.Insert("Key", account); 
} 

이 는 기본적으로 경쟁 조건의 예입니다

두 개 이상의 사용자가 액세스하는 동시에 동일한 공유 데이터를 변경하지만 그 일을 끝낼려고 할 때 경쟁 조건이 있습니다 잘못된 순서로

분산 잠금에서 위의 코드에 대한 대답은

LockHandle lockHandle = new LockHandle(); 

// Specify time span of 10 sec for which the item remains locked 
// NCache will auto release the lock after 10 seconds. 
TimeSpan lockSpan = new TimeSpan(0, 0, 10); 

try 
{ 
    // If item fetch is successful, lockHandle object will be populated 
    // The lockHandle object will be used to unlock the cache item 
    // acquireLock should be true if you want to acquire to the lock. 
    // If item does not exists, account will be null 
    BankAccount account = cache.Get(key, lockSpan, 
    ref lockHandle, acquireLock) as BankAccount; 
    // Lock acquired otherwise it will throw LockingException exception 

    if(account != null && account.IsActive) 
    { 
     // Withdraw money or Deposit 
     account.Balance += withdrawAmount; 
     // account.Balance -= depositAmount; 

     // Insert the data in the cache and release the lock simultaneously 
     // LockHandle initially used to lock the item must be provided 
     // releaseLock should be true to release the lock, otherwise false 
     cache.Insert("Key", account, lockHandle, releaseLock); 
    } 
    else 
    { 
     // Either does not exist or unable to cast 
     // Explicitly release the lock in case of errors 
     cache.Unlock("Key", lockHandle); 
    } 
} 
catch(LockingException lockException) 
{ 
    // Lock couldn't be acquired 
    // Wait and try again 
} 

이 답변은 NCache (A 분산 캐시)에 매우 특이하다. 난 당신이

Source

0

당신이 스플 라이스 기계에서 모습을 촬영 한 키워드`분산 잠금 "에서 더 많은 해결책을 찾을 거라고 확신 해? 그것은 완전히 위에서 실행 ACID 호환되는 RDBMS이다 hadoop 스택 (hbase, spark, hdfs, zookeeper). 빠른 OLTP 쿼리에 hbase를 사용하고 OLAP 쿼리를 실행하는 이중 아키텍처가 있으며 잠금을 필요로하지 않는 트랜잭션 기능이 내장되어 있습니다.