복붙노트

[REDIS] 어떻게 노드 JS + 레디 스 + MongoDB를 웹 응용 프로그램에서 경쟁 조건을 해결하기 위해

REDIS

어떻게 노드 JS + 레디 스 + MongoDB를 웹 응용 프로그램에서 경쟁 조건을 해결하기 위해

나는 많은 트랜잭션을 두 번째를 처리하는 웹 응용 프로그램을 구축하고있다. 나는 노드 JS와 익스프레스 서버를 사용하고 있습니다. 데이터베이스 측면에서, 나는 지속적으로 주가에 따라 변동될 사용자의 속성을 저장하는 레디 스를 사용하고 있습니다. 나는 등 주문 구성, 사용자 구성, 같은 반영구적 인 특성을 저장하기 위해 MongoDB를 사용하고 있습니다

사용자가 배치 여러 개의 주문을 동시에 처리되고 있지만, 단 하나의 여백이 트랜잭션을 모두 허용하지 않았을 저장 레디 스 속성에 대한 확인 등의 자격을했을 때 나는 경쟁 조건을 타격하고있다.

또 다른 문제는 레디 스 및 MongoDB를가 + 쓰기 호출을 읽을 인터리브 내 응용 프로그램 논리입니다. 어떻게 내가는 DB에 모두 걸쳐 경쟁 조건을 해결하는 갈 것입니다

나는 확실히 하나의 트랜잭션이 주어진 사용자에 대한 한 번에 발생하기 위해서는 시계와 레디 스에 MULTI + EXEC하려고 생각하고 있습니다. 아니면 내가 주문을 하나씩 처리 할 노드 / 레디 스에 대기열을 설정할 수 있습니다. 나는 올바른 접근 방식이다 모르겠습니다. 또는 어떻게 구현에 대한 이동합니다.

이것은 모든 의사입니다. 응용 프로그램 로직은 여러 조건으로 훨씬 더 복잡하다. 내 전체 애플리케이션 로직 (나는 나쁜 일이라고 생각) 중요한 부분입니다 같은 느낌


//The server receives a request from Client to place an Order
getAvailableMargin(user.username).then((margin) => { // REDIS call to fetch margin of user. This fluctuates a lot, so I store it in REDIS
            if (margin > 0) {
                const o = {  // Prepare an order
                    user: user.username,
                    price: orderPrice,
                    symbol: symbol
                }

                const order = new Order(o);
                order.save((err, o) => { // Create new Order in MongoDB
                        if (err) {
                            return next(err);
                        }
                        User.findByIdAndUpdate(user._id, {
                            $inc: {
                                balance: pl
                            }
                        }) // Update balance in MongoDB
                        decreaseMargin(user.username) //  decrease margin of User in REDIS
                    );

                }

            });



마진이 1 인 각각의 신규 수주 이익률은 1 씩 감소와 함께 고려한다.

이 요청이 동시에 수신하는 경우 이제 다음 레디 스의 마진 따라서 경쟁 조건을 일으키는 원인이 모두 요청에 대해 1이 될 것이다. 또한,이 개 주문은 지금의 결과로 MongoDB를 오픈 될 것입니다. 첫 번째 순서의 끝에 사실, 마진이 0이되어 있어야 할 때 2 차 거부되어 있어야합니다. 또 다른 문제는 우리가 앞서 간 및 각 주문에 대해 두 번 MongoDB의에서 사용자에 대한 균형, 하나를 업데이트 한 것입니다.

기대는 명령 중 하나가 실행되지해야하며 재 시도가 레디 스의 새로운 마진을 확인하여 일해야한다는 것입니다. 그리고 사용자의 균형은 한 번만 업데이트해야합니다.

기본적으로, 레디 스 및 MongoDB를 모두 시계를 구현해야합니다 경우 어떻게 든 트랜잭션을 다시 시도 감시 필드 / 문서 변화의? 그조차 할 수 있습니까? 아니면이 누락 될 수 있음을 훨씬 더 간단한 해결책이있다?

해결법

    from https://stackoverflow.com/questions/55469691/how-to-fix-a-race-condition-in-node-js-redis-mongodb-web-application by cc-by-sa and MIT license