question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

java.lang.IllegalStateException: Cannot create asynchronous query while in a write transaction in /Users/cm/Realm/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_Collection.cpp line 310

See original GitHub issue

Goal

Avoid crashes.

Expected Results

Crashes do not happen. Transactions completes successful without crashes. Also I want to know what kind of code can lead to this crash.

Actual Results

Error. StackTrace:

java.lang.IllegalStateException: Cannot create asynchronous query while in a write transaction in /Users/cm/Realm/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_Collection.cpp line 310
	at io.realm.internal.Collection.nativeStartListening(Native Method)
	at io.realm.internal.Collection.addListener(Collection.java:490)
	at io.realm.internal.Collection.addListener(Collection.java:497)
	at ...

Steps & Code to Reproduce

I do not know how to reproduce it. I haven’t got anything helpful after searching all the issues and in stackoverflow.com. And I also searched the crash message Cannot create asynchronous query while in a write transaction in realm source code but found nothing. It’s not a new issue and I first found this crash about one month ago. I found some similar problems in I-OS Realm, but there is no information about the solution https://github.com/realm/realm-cocoa/issues/4539 https://github.com/realm/realm-cocoa/issues/4231 https://stackoverflow.com/questions/42012222/realm-why-are-notification-blocks-triggered-when-a-write-transaction-begins

Code Sample

I’ve read the doc and cannot find what’s wrong with my code. I know how to avoid common problems like nested transactions. But this one is killing me. Our application (en.techops.brief) uses several threads and asynchronous transactions. The problem periodically occurs in different parts of the code, here are two cases and a stacktrace:

Case 1: Useq StackTrace: https://gist.github.com/andrey7mel/e121d0e856bb20d536d970a314bdf3b0 Realm 3.3.0

05-25 18:25:02.659 15486-15486/ru.techops.brief.debug E/REALM_JNI: jni: ThrowingException 8, Cannot create asynchronous query while in a write transaction in /Users/cm/Realm/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_Collection.cpp line 310, .
05-25 18:25:02.659 15486-15486/ru.techops.brief.debug E/REALM_JNI: Exception has been thrown: Cannot create asynchronous query while in a write transaction in /Users/cm/Realm/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_Collection.cpp line 310
05-25 18:25:02.666 15486-15486/ru.techops.brief.debug E/ChatPresenter.l()[351]: Error while getting chat events: 
java.lang.IllegalStateException: Cannot create asynchronous query while in a write transaction in /Users/cm/Realm/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_Collection.cpp line 310
	at io.realm.internal.Collection.nativeStartListening(Native Method)
	at io.realm.internal.Collection.addListener(Collection.java:490)
	at io.realm.internal.Collection.addListener(Collection.java:497)
	at io.realm.RealmResults.addChangeListener(RealmResults.java:171)
	at io.realm.rx.RealmObservableFactory$6.call(RealmObservableFactory.java:153)
	at io.realm.rx.RealmObservableFactory$6.call(RealmObservableFactory.java:137)
	at rx.Observable.unsafeSubscribe(Observable.java:10256)
	at rx.internal.operators.OnSubscribeFilter.call(OnSubscribeFilter.java:45)
	at rx.internal.operators.OnSubscribeFilter.call(OnSubscribeFilter.java:30)
	at rx.Observable.unsafeSubscribe(Observable.java:10256)
	at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)
	at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)
	at rx.Observable.unsafeSubscribe(Observable.java:10256)
	at rx.internal.operators.OperatorSwitch$SwitchSubscriber.onNext(OperatorSwitch.java:155)
	at rx.internal.operators.OperatorSwitch$SwitchSubscriber.onNext(OperatorSwitch.java:77)
	at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:77)
	at rx.internal.operators.OperatorCast$CastSubscriber.onNext(OperatorCast.java:69)
	at rx.internal.operators.OnSubscribeFilter$FilterSubscriber.onNext(OnSubscribeFilter.java:76)
	at rx.internal.operators.OnSubscribeFilter$FilterSubscriber.onNext(OnSubscribeFilter.java:76)
	at io.realm.rx.RealmObservableFactory$10$1.onChange(RealmObservableFactory.java:293)
	at io.realm.rx.RealmObservableFactory$10$1.onChange(RealmObservableFactory.java:289)
	at io.realm.ProxyState$RealmChangeListenerWrapper.onChange(ProxyState.java:46)
	at io.realm.internal.OsObject$ObjectObserverPair.onChange(OsObject.java:69)
	at io.realm.internal.OsObject$Callback.onCalled(OsObject.java:88)
	at io.realm.internal.OsObject$Callback.onCalled(OsObject.java:73)
	at io.realm.internal.ObserverPairList.foreach(ObserverPairList.java:108)
	at io.realm.internal.OsObject.notifyChangeListeners(OsObject.java:236)
	at io.realm.internal.SharedRealm.nativeBeginTransaction(Native Method)
	at io.realm.internal.SharedRealm.beginTransaction(SharedRealm.java:262)
	at io.realm.BaseRealm.beginTransaction(BaseRealm.java:348)
	at io.realm.BaseRealm.beginTransaction(BaseRealm.java:343)
	at io.realm.Realm.beginTransaction(Realm.java:131)
	at io.realm.Realm.executeTransaction(Realm.java:1441)
	at ru.techops.brief.model.database.DataBase.executeTransaction(DataBase.java:1720)
	at ru.techops.brief.model.database.DataBase.lambda$null$1(DataBase.java:149)
	at ru.techops.brief.model.database.DataBase$$Lambda$160.call(Unknown Source)
	at rx.internal.operators.OnSubscribeCreate.call(OnSubscribeCreate.java:72)
	at rx.internal.operators.OnSubscribeCreate.call(OnSubscribeCreate.java:32)
	at rx.Observable.unsafeSubscribe(Observable.java:10256)
	at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.drain(OnSubscribeConcatMap.java:286)
	at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.onNext(OnSubscribeConcatMap.java:144)
	at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:224)
	at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:107)
	at android.os.Handler.handleCallback(Handler.java:751)
	at android.os.Handler.dispatchMessage(Handler.java:95)
	at android.os.Looper.loop(Looper.java:154)
	at android.app.ActivityThread.main(ActivityThread.java:6688)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

Code transaction:

// ru.techops.brief.model.database.DataBase.lambda$null$1(DataBase.java:149)
saveUseqSubject
                .onBackpressureLatest()
                .concatMap(useq -> Observable.create(emitter -> {
                    executeTransaction(realm -> {
                        Useq useqObj = realm.where(Useq.class).findFirst();
                        if (useqObj == null) {
                            useqObj = new Useq();
                        }
                        useqObj.setUseq(useq);
                        realm.insertOrUpdate(useqObj);
                        emitter.onNext(useq);
                    });
                }, Emitter.BackpressureMode.BUFFER))
                .subscribe(useq1 -> Timber.v("Saved to database Useq=" + useq1),
                        e -> Timber.e(e, "Error while saving useq to Realm"));

//ru.techops.brief.model.database.DataBase.executeTransaction(DataBase.java:1720)
private void executeTransaction(Realm.Transaction transaction) {
   try (Realm realm = getRealm()) {
       realm.executeTransaction(transaction);
   }
}
 

Case 2: SaveEvents Stacktrace: https://gist.github.com/andrey7mel/10e6b54e741d99d08bd2f6174cece094 Realm 3.1.4

Non-fatal Exception: java.lang.IllegalStateException: Cannot create asynchronous query while in a write transaction in /home/cc/repo/realm/release/realm/realm-library/src/main/cpp/io_realm_internal_Collection.cpp line 310
   at io.realm.internal.Collection.nativeStartListening(Collection.java)
   at io.realm.internal.Collection.addListener(Collection.java:490)
   at io.realm.internal.Collection.addListener(Collection.java:497)
   at io.realm.RealmResults.addChangeListener(RealmResults.java:136)
   at io.realm.rx.RealmObservableFactory$6.call(RealmObservableFactory.java:153)
   at io.realm.rx.RealmObservableFactory$6.call(RealmObservableFactory.java:137)
   at rx.Observable.unsafeSubscribe(Observable.java:10346)
   at rx.internal.operators.OnSubscribeFilter.call(OnSubscribeFilter.java:45)
   at rx.internal.operators.OnSubscribeFilter.call(OnSubscribeFilter.java:30)
   at rx.Observable.unsafeSubscribe(Observable.java:10346)
   at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)
   at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)
   at rx.Observable.unsafeSubscribe(Observable.java:10346)
   at rx.internal.operators.OperatorSwitch$SwitchSubscriber.onNext(OperatorSwitch.java:155)
   at rx.internal.operators.OperatorSwitch$SwitchSubscriber.onNext(OperatorSwitch.java:77)
   at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:77)
   at rx.internal.operators.OperatorCast$CastSubscriber.onNext(OperatorCast.java:69)
   at rx.internal.operators.OnSubscribeFilter$FilterSubscriber.onNext(OnSubscribeFilter.java:76)
   at rx.internal.operators.OnSubscribeFilter$FilterSubscriber.onNext(OnSubscribeFilter.java:76)
   at io.realm.rx.RealmObservableFactory$10$1.onChange(RealmObservableFactory.java:293)
   at io.realm.rx.RealmObservableFactory$10$1.onChange(RealmObservableFactory.java:289)
   at io.realm.ProxyState$RealmChangeListenerWrapper.onChange(ProxyState.java:46)
   at io.realm.internal.OsObject$ObjectObserverPair.onChange(OsObject.java:67)
   at io.realm.internal.OsObject$Callback.onCalled(OsObject.java:86)
   at io.realm.internal.OsObject$Callback.onCalled(OsObject.java:71)
   at io.realm.internal.ObserverPairList.foreach(ObserverPairList.java:108)
   at io.realm.internal.OsObject.notifyChangeListeners(OsObject.java:149)
   at io.realm.internal.SharedRealm.nativeBeginTransaction(SharedRealm.java)
   at io.realm.internal.SharedRealm.beginTransaction(SharedRealm.java:246)
   at io.realm.BaseRealm.beginTransaction(BaseRealm.java:309)
   at io.realm.Realm.beginTransaction(Realm.java:128)
   at io.realm.Realm.executeTransaction(Realm.java:1408)
   at ru.techops.brief.model.database.DataBase.executeTransaction(DataBase.java:1729)
   at ru.techops.brief.model.database.DataBase.saveEventsSync(DataBase.java:636)
   at ru.techops.brief.model.Model.lambda$saveEventsSync$85(Model.java:888)
   at ru.techops.brief.model.Model$$Lambda$70.call(Unknown Source)
   at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:69)
   at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:276)
   at rx.internal.producers.ProducerArbiter.setProducer(ProducerArbiter.java:126)
   at rx.internal.operators.OnSubscribeConcatMap$ConcatMapInnerSubscriber.setProducer(OnSubscribeConcatMap.java:329)
   at rx.internal.operators.OnSubscribeMap$MapSubscriber.setProducer(OnSubscribeMap.java:102)
   at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:138)
   at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:129)
   at rx.Observable.unsafeSubscribe(Observable.java:10346)
   at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)
   at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)
   at rx.Observable.unsafeSubscribe(Observable.java:10346)
   at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.drain(OnSubscribeConcatMap.java:286)
   at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.innerCompleted(OnSubscribeConcatMap.java:209)
   at rx.internal.operators.OnSubscribeConcatMap$ConcatMapInnerSubscriber.onCompleted(OnSubscribeConcatMap.java:345)
   at rx.observers.SerializedObserver.onCompleted(SerializedObserver.java:176)
   at rx.observers.SerializedSubscriber.onCompleted(SerializedSubscriber.java:64)
   at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.drain(OnSubscribeConcatMap.java:246)
   at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.innerCompleted(OnSubscribeConcatMap.java:209)
   at rx.internal.operators.OnSubscribeConcatMap$ConcatMapInnerSubscriber.onCompleted(OnSubscribeConcatMap.java:345)
   at rx.observers.SerializedObserver.onCompleted(SerializedObserver.java:176)
   at rx.observers.SerializedSubscriber.onCompleted(SerializedSubscriber.java:64)
   at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.drain(OnSubscribeConcatMap.java:246)
   at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.innerCompleted(OnSubscribeConcatMap.java:209)
   at rx.internal.operators.OnSubscribeConcatMap$ConcatMapInnerSubscriber.onCompleted(OnSubscribeConcatMap.java:345)
   at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:656)
   at rx.internal.operators.OperatorMerge$MergeSubscriber.emit(OperatorMerge.java:568)
   at rx.internal.operators.OperatorMerge$MergeSubscriber.onCompleted(OperatorMerge.java:281)
   at rx.internal.operators.OnSubscribeMap$MapSubscriber.onCompleted(OnSubscribeMap.java:97)
   at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onCompleted(OperatorOnErrorResumeNextViaFunction.java:101)
   at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.checkTerminated(OperatorObserveOn.java:281)
   at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:216)
   at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:107)
   at android.os.Handler.handleCallback(Handler.java:815)
   at android.os.Handler.dispatchMessage(Handler.java:104)
   at android.os.Looper.loop(Looper.java:207)
   at android.app.ActivityThread.main(ActivityThread.java:5896)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:948)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:809)

Code:

// ru.techops.brief.model.Model.lambda$saveEventsSync$85(Model.java:888)
 public Completable saveEventsSync(List<WsUpdateEventNew> updates) {
        List<Event> events = new ArrayList<>();
        for (WsUpdateEventNew update : updates) {
            events.add(update.getEvent());
        }
        return Observable.from(events)
                .concatMap(event -> {
                    Observable<Object> res = Observable.empty();
                    User sender = dataBase.getUserSyncFromRealm(event.getSenderId());
                    if (sender == null) {
                        res = res.concatWith(getUserInfoFromServer(event.getSenderId()));
                    }
                    Peer fwdSenderPeer = event.getFwdSenderPeer();
                    if (fwdSenderPeer != null) {
                        User fwdSender = dataBase.getUserSyncFromRealm(fwdSenderPeer.getPeerId());
                        if (fwdSender == null) {
                            res = res.concatWith(getUserInfoFromServer(fwdSenderPeer.getPeerId()));
                        }
                    }
                    Peer peer = event.getPeer();
                    Const.NotifyMode notifyMode = dataBase.getPeerNotifyMode(peer);
                    if (notifyMode == Const.NotifyMode.NOTIFY_UNKNOWN) {
                        switch (peer.getType()) {
                            case PeerType.USER:
                                res = res.concatWith(getUserInfoFromServer(event.getPeer().getPeerId()));
                                break;
                            case PeerType.GROUP:
                                res = res.concatWith(getGroupInfoFromServer(event.getPeer().getPeerId()));
                                break;
                        }
                    }
                    if (event.getReplyToId() != 0) {
                        res = res.concatWith(loadEventIfNeed(event.getPeer(), event.getReplyToId()).ignoreElements());
                    }
                    return res;
                })
                .concatWith(Observable.just(events)
                        .map(e -> {
                        // (Model:888)       
                            dataBase.saveEventsSync(e);
                            return e;
                        }))
                .toCompletable();
    }
 
 
//ru.techops.brief.model.database.DataBase.saveEventsSync(DataBase.java:636)
@WorkerThread
public void saveEventsSync(List<Event> events) {
    executeTransaction(realm -> {
       for (Event event : events) {
           saveEventToRealm(event, realm);
       }
   });
}


// ru.techops.brief.model.database.DataBase.executeTransaction(DataBase.java:1729)
    private void executeTransaction(Realm.Transaction transaction) {
        try (Realm realm = getRealm()) {
            realm.executeTransaction(transaction);
        }
    }

Version of Realm and tooling

Realm version(s): 3.1.4 - 3.3.0

Realm sync feature enabled: no

Android Studio version: 2.3.2

Which Android version and device: Android 5 - 6 - 7, many devices image

Issue Analytics

  • State:open
  • Created 6 years ago
  • Comments:7 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
beeendercommented, May 30, 2017

@cmelchior due to the nature of how Object Store running the queries, even findAll() will be put into background thread if it is possible. That means calling findAll().addChangeListener() inside a transaction is not allowed as well.

0reactions
andrey7melcommented, May 30, 2017

@cmelchior

private void saveEventToRealm(Event event, Realm bgRealm) {
        User sender = bgRealm.where(User.class).equalTo("id", event.getSenderId()).findFirst();
        if (sender != null) {
            event.setSender(sender);
        }
        if (event.getFwdSenderPeer() != null) {
            User fwdUser = bgRealm.where(User.class).equalTo("id", event.getFwdSenderPeer().getPeerId()).findFirst();
            if (fwdUser != null) {
                event.setFwdSender(fwdUser);
            }
        }

        ServiceAction action = event.getAction();
        if (action != null && action.getUserId() != 0) {
            User actionUser = bgRealm.where(User.class).equalTo("id", action.getUserId()).findFirst();
            if (actionUser != null) {
                action.setUser(actionUser);
                event.setAction(action);
            }
        }

        if (event.getReplyToId() != 0) {
            setReplyEvent(event, bgRealm);
        }

        event.setState(Event.EventState.SENT);

        FileBrief file = event.getFile();
        if (file != null && event.getFile() != null) {
            file.setId(event.getFile().getId());
        }

        Event eventRealm = bgRealm.copyToRealmOrUpdate(event);

        Chat chat = bgRealm.where(Chat.class)
                .equalTo("peer.uniquePeerId", event.getPeer().getUniquePeerId())
                .findFirst();

        if (chat != null) {
            if (event.getSenderId() != getSelfUserId() && event.getId() > chat.getReadEventId()) {
                int unreadCount = chat.getUnreadCountSafe();
                chat.setUnreadCount(unreadCount + 1);
            }
            Timber.d("Chat " + chat.getChatName() + " , set last  event - " + event.getText());
            chat.setLastEvent(eventRealm);

        } else {
            Timber.i("Chat == null in saveEvent => create new chat");
            if (event.getPeer().getType().equals(PeerType.USER)) {
                User user = bgRealm.where(User.class).equalTo("id", event.getPeer().getPeerId()).findFirst();
                if (user != null) {
                    chat = new Chat(event.getPeer(), eventRealm, user);
                    bgRealm.insertOrUpdate(chat);
                } else {
                    Timber.e("Chat == null, user == null, can't create Chat");
                }
            } else {
                Group group = bgRealm.where(Group.class).equalTo("id", event.getPeer().getPeerId()).findFirst();
                if (group != null) {
                    chat = new Chat(event.getPeer(), eventRealm, group);
                    bgRealm.insertOrUpdate(chat);
                } else {
                    Timber.e("Chat == null, group == null, can't create Chat");
                }
            }

            if (chat != null) {
                if (event.getAction() != null) {
                    if (ServiceAction.ACTION_GROUP_CREATED.equals(event.getAction().getType())
                            && event.getSenderId() != getSelfUserId()) {
                        // если группу создал не я
                        chat.setUnreadCount(1);
                    }
                    if (!ServiceAction.ACTION_GROUP_CREATED.equals(event.getAction().getType())) {
                        chat.setUnreadCount(1);
                    }
                }
                bgRealm.insertOrUpdate(chat);
            } else {
                Timber.e("Chat == null or group == null, can't create Chat in saveEventToRealm");
            }
        }
    }
Read more comments on GitHub >

github_iconTop Results From Across the Web

Cannot create asynchronous query while in a write transaction ...
Hi, I keep getting this crash and has affected significant number of users. Usecase: Profile page which fetches data from two different asynchronous...
Read more >
Realm "Cannot create asynchronous query" while using ...
This happens if you have a UI-thread write transaction and also have a RealmChangeListener in which you also execute an async query (or ......
Read more >
Cannot create asynchronous query while in a write transaction ...
When a user sends a message, the app receives the data via a websocket or other means (i.e. push notification) and writes it...
Read more >
Synchronous, asynchronous, and cursored search - IBM
To initiate a query string search using methods, set the properties on the bean for synchronous or asynchronous search, maximum search results, and...
Read more >
DataStax Java Driver - Asynchronous programming
The driver exposes an asynchronous API that allows you to write programs ... Here is a short example that opens a session and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found