본문 바로가기
End/#11 달과 별 그리고 술

[Android/달과 별 그리고 술]개발 문서 #12, Firebase Transaction

by 퍼즐잎 2017. 8. 23.



1. 한동안 기타 버그 수정과 콘텐츠 추가 작업을 진행했다.




현재는 소주, 맥주, 막걸리를 포함해서 85종의 술 종류가 들어있다.


이번에 술 종류를 추가하면서 이렇게 많은 술들이 있는 줄 처음 알았다....


너무 많은 종류가 있어서 100개 까지만 채우고 


이후에는 사용자들이 제보할 수 있는 항목을 따로 둘 생각이다.




2. Firebase Transaction을 사용하면서 로그를 찍어보니 2번씩 동작하는 현상을 발견했다.


[https://firebase.google.com/docs/database/admin/save-data?hl=ko#section-transactions]


문서를 확인해보면 다음과 같은 내용이 써 있었다.


트랜잭션 핸들러가 이럴 때 여러번 호출되는 것을 확인했다.


만약 내가 트랜잭션 핸들러로 데이터를 새로 저장하거나, 업데이트 한다고 할 때

만약 새로 저장하는 경우에는 Firebase의 RealTime DataBase 상에 아무것도 존재하지 않는다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Firebase참조.runTransaction(new Transaction.Handler() {
                    @Override
                    public Transaction.Result doTransaction(MutableData mutableData) {
                        내클래스 인스턴스 = mutableData.getValue(내클래스.class);
                        if(인스턴스 == null){
                            인스턴스 = new 내클래스();
                        }else{
                            인스턴스.수정한다(데이터 업데이트);
                        }
                        mutableData.setValue(인스턴스);
                        return Transaction.success(mutableData);
                    }
                    @Override
                    public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
                       모든 작업 수행이 끝난 이후 동작
                    }
                });
cs



대략 이런 느낌이라고 할 때 Firebase 참조에서 내가 데이터를 가지고 와서(mutableData를 통해) 인스턴스로 만든다고 할 때

새로 저장하는 경우이므로 당연히 인스턴스null에 걸리게 된다.


new를 통해서 새로운 인스턴스를 생성하게 되고 

mutableData.setValue(인스턴스); 를 통해 저장이 된다.



이제 새로 저장하는 경우가 아닌 데이터를 업데이트 하는 경우라고 한다면 어떨까?


내클래스 인스턴스 = mutableData.getValue(내클래스.class); 이 부분에서 데이터를 가지고 올 때

참조가 정확하다면 null이 아니어야 할 것이다.



그러나 null을 가지고 오는 경우가 발생한다.


이유는 문서에 써 있는 내용 그대로 로컬에 캐시된 데이터가 없기 때문이다.


이 경우에 처음에는 null에 걸려서 새로운 인스턴스를 생성하고 

return Transaction.success(mutableData); 이후에 doTransaction을 한번 더 수행한다.


Firebase Database 상에 데이터가 존재하면

mutableData.setValue(인스턴스); 을 통해서 값을 덮어 씌우지 않는다.


doTransaction을 한번 더 수행하면서 기존에 있는 데이터를 가지고 오게 되고

(이때는 null에 걸리지 않는다)


데이터 업데이트를 수행하게 된다.




댓글