2013-04-20 5 views
4

NodeJS에서 Firebase 트랜잭션을 정의 할 때마다 항상 3 번 실행됩니다. 첫 번째는 null 데이터로, 두 번째로는 실제로 데이터로 세 번째입니다. 이것은 정상입니까/의도입니까?NodeJS의 Firebase 트랜잭션은 항상 3 번 실행됩니까?

예를 들어,이 코드 :

firebaseOOO.child('ref').transaction(function(data) { 
    console.log(data); 
    return data; 
}); 

는 다음을 출력합니다

null 
null 
i1: { a1: true } 

나는 그것이 마지막 항목을 인쇄 할 것으로 예상했을 것이다.

firebaseOOO.child('ref').transaction(function(data) { 
    console.log(data); 
    return data; 
}, function(error, committed, snapshot) { 
    if (error) 
     console.log('failed'); 
    else if (!committed) 
     console.log('aborted'); 
    else 
     console.log('committed'); 
    console.log('fin'); 
}); 

다음과 같은 출력 산출 : 나는 거래하기 전에 작동하는 방법의 세부 사항을 읽은

null 
null 
i1: { a1: true } 
committed 
fin 

이 코멘트에서 질문에 대답하기 위해, 여기 콜백과 동일 질문을 게시, 그래서 나는 다음과 같이 false로 applyLocally 설정을 시도했다 :

firebaseOOO.child('ref').transaction(function(data) { 
    console.log('hit'); 
    return data; 
}, function(){}, false); 

그러나 그것은 여전히 ​​3 번 (그냥 더블 체크)을 눌렀습니다. 그래서 나는 그것이 다른 것이라고 생각했습니다. 거래 전에 '가치'를 얻는 것은 예상대로 작동합니다. 이는 한 번만 적용되며 적용되는 지역에 상관없이 적용됩니다. 따라서 적용 가능한 항목이 확실하지 않습니다. 이것은 내가 거래를하기 전에 값을 받고 무엇을 의미하는 것입니다 :

firebaseOOO.child('ref').once('value', function(data) { 
    console.log('1'); 
    firebaseOOO.child('ref').transaction(function(data) { 
     console.log('2'); 
     return data; 
    }); 
}); 

출력을 :

1 
2 

@Michael : 어떻게이 동작을 사용할 수있다? 트랜잭션은 기본적으로 자체 수정을 위해 데이터 자체를 사용하기위한 것입니다. 이는 원형 증가 ++ 시나리오입니다. 따라서 기존 값인 10에 1을 더하고 11의 결과로 작업을 계속해야한다면 처음 두 번 함수가 나에게 내가 처리해야하는 1의 잘못된 결과를 갖게 될 것입니다. 세 번째 히트에 11. 처음 두 1을 어떻게 활용할 수 있습니까? 또 다른 시나리오 (그리고 어쩌면이 트랜잭션을 사용해서는 안된다.하지만 코드가 깨끗해지기를 기대했던 것처럼 작동한다면)은 아직 존재하지 않는다면 값을 삽입하는 것이다. 거래가 한 번만 발생하면 null 값은 값이 존재하지 않는다는 것을 의미하므로 예를 들어 카운터를 1로 초기화 할 수 있습니다. 그렇지 않으면 값이 무엇이든간에 1을 추가하십시오. 시끄러운 nulls로, 이것은 불가능합니다.

이 모든 것에서 테이크 어웨이가 단순히 '한 번'패턴을 더 자주 사용하는 것 같습니다. TRANSACTION의 패턴 ONCE

:

firebaseOOO.child('ref').once('value', function(data) { 
    console.log('1'); 
    firebaseOOO.child('ref').transaction(function(data) { 
     console.log('2'); 
     return data; 
    }); 
}); 
+0

이것은 상당히 이상한 거래입니다. 왜 정확히 같은 값으로 다시 설정하고 싶습니까? 두 번째 콜백을 설정하면 무엇을 말합니까? 커밋이 성공 했습니까? 오류가 있습니까? – Kato

+0

안녕하세요, 카토. 내 문제를 설명하는 가장 간단한 사례입니다. 내 실제 코드에는 훨씬 더 많은 논리가 있습니다. 오류 메시지가 없으며 결과가 끝에 성공적으로 기록됩니다. 실제로 예상대로 마지막에 커밋 메시지가 하나만 있습니다. 이 결과를 반영하기 위해 질문을 업데이트했습니다. – Baz

답변

2

는 여기보고있는 동작은 중포 기지는 중포 기지 서버와 동기화 결국 다음 지역 행사를 발생하는 방법과 관련이있다. 이 특정 예제에서 "3 회 실행"은 코드를 처음 실행했을 때만 발생합니다. 상태가 완전히 동기화되고 이후부터 한 번 트리거됩니다. 이 동작은 다음과 같습니다. https://www.firebase.com/docs/transactions.html ("트랜잭션이 실행될 때 다음과 같은 경우"절을 참조하십시오.)

예를 들어 동일한 위치에 미해결 된 on()이 있고 나중에 이 동일한 트랜잭션 코드를 실행하면 한 번 실행됩니다.이것은 트랜잭션 실행 이전에 모든 것이 동기화되어 있기 때문입니다 (이상적인 경우에는 정상적인 충돌을 제외하고).

+1

설명하는 내부 이벤트로 인해 null을 구분할 수있는 방법과 객체가 Firebase에 아직 존재하지 않는 "실제"null을 구분할 수 있습니까? – Baz

+2

'value'이벤트에 대한 리스너를 동일한 위치에 추가하고 트랜잭션 호출에서 applyLocally를 false로 설정할 수 있습니다. 이렇게하면 트랜잭션의 최종 값이 설정되면 값 이벤트 리스너가 트리거됩니다. 여기에서 거래 문서를 보려면 applyLocally 매개 변수를 확인하십시오. https://www.firebase.com/docs/javascript/firebase/transaction.html –

+1

또한 사용 사례에 관심이 있으며 null이 실제로 문제를 일으킨다. 지금 우리는 데이터를 동기화하기 전에 트랜잭션을 낙관적으로 실행합니다. 따라서 'null'이 표시되고 지금까지는 제대로 작동했습니다. 그러나 우리는 행동을 바꾸는 것을 고려했습니다. 유스 케이스에 대한 자세한 내용을 공유하고 싶다면 firebase com의 Ping michael! –

0

transaction()은 여러 번 호출되며 null 데이터를 처리 할 수 ​​있어야합니다. 데이터베이스에 기존 데이터가있는 경우에도 트랜잭션 기능이 실행될 때 로컬로 캐시되지 않을 수 있습니다.

firebaseOOO.child('ref').transaction(function(data) { 

if(data!=null){ 
    console.log(data); 
    return data; 
} 
else { 
    return data; 
} 
}, function(error, committed, snapshot) { 
    if (error) 
     console.log('failed'); 
    else if (!committed) 
     console.log('aborted'); 
    else 
     console.log('committed'); 
    console.log('fin'); 
}); 
관련 문제