2012-07-25 2 views
4

나는 약 진짜 돈을 거래node.js와 noSQL db를 사용하여 트랜잭션 처리를 수행 할 수 있습니까?

내가 맡은 프로젝트를 이야기하고 있지 않다 것은 플레이어가 서로 사이에 물건을 무역 게임이다. 그것은 기본적으로 거래 프로세스입니다. 플레이어 A는 30 마리의 암소와 교환하여 플레이어 B 10 그루트를줍니다. 당신은 아이디어를 얻습니다.

하지만 대화 형이고 여러 플레이어가 한꺼번에 채팅 룸과 같은 환경에서 무작위로 거래하는 경우 node.js과 같은 일을 할 수 있는지 궁금해했지만 문제가 있습니다.

데이터베이스 상태를 유지하기 위해 처리 트랜잭션과 rollbackcommit의 성격이 필요한 DB 배경에서 왔습니다. 그러나 우리가 node.js 더하기 mongoDB (또는 그 문제에 대한 다른 noSQL DB)을 말하고 있다면 분명히 전체적인 사고 방식이지만, 단지 두 당사자 만 참여해야한다는 의미에서 거래를 처리하는 방법을 알지 못합니다. 어떤 형태의 잠금에 의지하지 않고, 확실하게 그것은 node이 아닌 것입니다.

아직 아무 것도 발견하지 못했지만, node.js은 너무 새롭기 때문에 저를 놀라게하지 않습니다.

업데이트 나는 거래의 메커니즘, 특히 뱅킹 스타일 트랜잭션을 알고 있지만, 이것은 똑같은 것이 아닙니다. 나는 그것을 명확하게하지 않았지만, 문제는 플레이어 B가 구매자 공동체에 무언가를 팔고 있다는 것입니다.

즉, 플레이어 A가 클라이언트 측에서 구매 지시를 시작하더라도 플레이어 C D 또는 E가 같은 암소를 구매할 때 거의 동시에 클릭 할 수도 있습니다.

이제 정상적인 거래에서 기록 수준 테이블 잠금을 얻은 사람 중 적어도 첫 번째 사람이 다른 사람이 그 시점에서 진행하는 것을 차단할 것으로 예상됩니다.

그러나 노드 사용의 특성과 특히 속도, 동시 처리 및 실시간 업데이트 데이터베이스 표시에 사용하면 가장 느린 사람 (우리가 말하는 밀리 초)이 쉽게 상상할 수 있습니다.

예를 들어 플레이어 A가 플레이어 C와 동시에 구매를 시작합니다. 플레이어 트랜잭션이 완료되고 Groats가 플레이어 B에게 지급되고 암소가 데이터베이스의 플레이어 A에 할당됩니다. 몇 초 후에 암소가 플레이어 C에게 할당됩니다.

나는이 문제를 더 잘 설명하기를 바랍니다.

답변

4

이것은 Node.JS와는 아무런 관련이 없습니다. Node.JS는 데이터베이스에만 연결되며 트랜잭션은 데이터베이스 자체에서 수행됩니다 (Node.JS에서 트랜잭션을 수동으로 구현하려는 경우가 아니라면 조금 어려울 수도 있지만 모든 언어로 작성된 웹 서버에서 동일합니다).

트랜잭션을 지원하는 Node.JS와 함께 MySQL을 쉽게 사용할 수 있습니다. 그래서 당신이 묻는 질문은 : MongoDB와의 거래를 할 수 있습니까? 대답은 '아니오'와 '예'입니다.

아니요. MongoDB는 기본적으로 트랜잭션을 지원하지 않기 때문에 아니오.

예, 일부 트릭을 사용하여 트랜잭션을 에뮬레이션 할 수 있기 때문에 가능합니다. 예를 들어 this article을 참조하십시오.

1

문서 데이터베이스와 뱅킹 스타일 트랜잭션을 수행하려면 일반적으로 트랜잭션 로그 패턴을 사용하는 것이 좋습니다. 이 패턴에서는 각 거래을 자신의 문서로 씁니다. 각 계정 잔액에 해당하는 문서는 유지 관리하지 않습니다. 대신 쿼리 시간에 거래 문서를 롤오버하여 현재 잔액을 제공합니다. http://guide.couchdb.org/draft/recipes.html

2

내가 Waterline라는 Node.js를위한 OSS 애플리케이션 레벨의 트랜잭션 데이터베이스에서 일하고 있어요 : 여기

감소 카우치베이스 주식회사지도에 적용 할 수있는 예이다.

우리는 full-on CRUD mutits로 시작했지만, 곧 꽤 어려웠다는 것을 깨달았습니다. 더 나은 것을 데이터베이스에 남겨 두는 것이 좋습니다. 그러나 때로는 데이터베이스를 전환하고 코드에 무관심하기를 원하기 때문에 원하지 않을 수도 있습니다. 그래서 우리는 거래라는 가장 쉬운 다음 작품으로 간소화했습니다.

그래서 롤백 지원 기능은 내장되어 있지 않습니다. (지금은 직접해야합니다.) 적어도 워터 라인은 동시 액세스를 방해합니다. 도움이

function buyCow (req,res) { 
    Cow.find(req.param('cowId'),function (err,cow) { 
     if (err) return req.send(500,err); 

     Cow.transaction('buy_cow',function (err, unlock) { 
     if (err) { 
      // Notice how I unlock before each exit point? REALLY important. 
      // (would love to hear thoughts on an easier way to do this) 
      unlock(); 
      return res.send(500,err); 
     } 

     User.find(req.session.userId,function (err,user) { 
      // If there's not enough cash, send an error 
      if (user.money - cow.price < 0) { 
       unlock(); 
       return res.send(500,'Not enough cash!'); 
      } 

      // Update the user's bank account 
      User.update(user.id,{ 
       money: user.money - cow.price 
      }, function (err,user) { 
       if (err) { unlock(); return res.send(500,err); } 

       Cow.update(cow.id, {owner: user.id}, function (err, cow) { 
        if (err) { unlock(); return res.send(500,err); } 

        // Success! 
        unlock(); 
        res.json({success: true}); 
       }); 

      }); 
     }); 
     }); 

    }); 
} 

희망 : 당신의 예에서

이 같이 보일 수도 있습니다 (이 표현에있어 가정// Sails 연결). 귀하의 의견을 환영합니다. (아마도 커밋합니까?)

+0

질문을 게시 한 이후로이 주제에 대한 지식이 거의 없기 때문에 프로젝트를 진행하기 위해 다른 트랙을 얻었지만 재미있을 수 있습니다. – T9b

+0

어쨌든, 어젯밤에 물줄기의 첫 번째 릴리스를 확인하고 싶습니다. http://github.com/mikermcneil/waterline dirtydb, 메모리 내장 데이터베이스를 사용하도록 설정되었습니다. . 내 다음 단계는 mongodb 어댑터를 작성한 다음 mySQL (mySQL 어댑터는 mySQL의 내장 트랜잭션을 사용합니다) – mikermcneil

관련 문제