는 다음 사항을 고려 버그 :이이 같은 노드 JS 과정에서 호출중포 기지 거래
function useCredits(userId, amount){
var userRef = firebase.database().ref().child('users').child(userId);
userRef.transaction(function(user) {
if (!user){
return user;
}
user.credits -= amount;
return user;
}, NOOP, false);
}
function notifyUser(userId, message){
var notificationId = Math.random();
var userNotificationRef = firebase.database().ref().child('users').child(userId).child('notifications').child(notificationId);
userNotificationRef.transaction(function(notification) {
return message;
}, NOOP, false);
}
.
는 사용자는 다음과 같습니다
{
"name": 'Alex',
"age": 22,
"credits": 100,
"notifications": {
"1": "notification 1",
"2": "notification 2"
}
}
내 스트레스 테스트를 실행하면 내가 가끔 userRef 트랜잭션 업데이트 함수에 전달 된 사용자 개체는 단지 다음 인 전체 사용자가 아닌 것을 알 수 :
{
"notifications": {
"1": "notification 1",
"2": "notification 2"
}
}
이것은 분명히 user.credits가 없기 때문에 오류가 발생합니다.
userRef 트랜잭션의 업데이트 기능에 전달 된 사용자 객체가 userNotificationRef 트랜잭션의 업데이트 기능에 의해 반환 된 데이터와 동일하다는 것은 의심스러운 사실입니다.
왜 이런 경우입니까? 이 문제는 사용자 상위 위치에서 두 트랜잭션을 모두 실행하면 사라지지만이 방법은 전체 사용자 개체를 효과적으로 잠그고 읽는 것과 같이 덜 최적의 솔루션입니다.이 개체는 한 번만 쓰는 알림을 추가 할 때 중복됩니다.
나는 거래에 이런 문제가 있다는 것을 알지 못했습니다 ... +1. 트랜잭션을 필요로하지 않고이 "가치 증대"작업을 어떻게 재 설계 할 것을 제안 하시겠습니까? – qxz
자세한 답변을 주셔서 대단히 감사합니다. 거래가 다소 망가져있는 것 같습니다. 클라이언트는 이러한 모든 고려 사항에 대해 걱정할 필요가 없습니다. 파이낸싱 거래를 사용하지 않고 은행 계좌 잔액을 모델링했다고 어떻게 제안 하시겠습니까? 트랜잭션을 사용하여 이것을 처리하는 강력한 방법이 없다면 나는 이것이 심각한 한계라고 느낀다. 또 다른 문제는 트랜잭션 적으로 일부 값을 업데이트하고 동시에 다른 위치를 원자 적으로 업데이트 할 수 있다는 것입니다. – user3391835
하드 코어 게임에 중점을 둔이 모든 것은 힘든 경험이었습니다. 트랜잭션은 위의주의 사항을 염두에두면 간단한 증분으로도 괜찮습니다. 또 다른 접근법은 로그에 "+ N"항목을 넣고 서버가 주기적으로 트랜잭션을 롤업하도록하는 것입니다. 트랜잭션은 더 강력하고 궁극적으로 일관성이 있어야합니다. 클라이언트는 마지막 집계 값과 로그를 읽고 현재 값을 즉시 계산할 수 있습니다. 깊은 원자 업데이트는 가능하지만 트랜잭션 적이 될 수 없습니다. 다시, 로그 기반 디자인은 여러분의 친구입니다. – Piotr