realm-swift: Crash: Cannot create asynchronous query while in a write transaction
Goals
Avoid crashes.
Expected Results
Crashes do not happen. Also I want to know what kind of code can lead to this crash.
Actual Results
Possible related threads are below.
Fatal Exception: realm::InvalidTransactionException: Cannot create asynchronous query while in a write transaction
Crashed: com.twitter.crashlytics.ios.exception
0 ?????? 0xfefe19 CLSProcessRecordAllThreads + 17612313
1 ?????? 0xfefe19 CLSProcessRecordAllThreads + 17612313
2 ?????? 0xfefd11 CLSProcessRecordAllThreads + 17612049
3 ?????? 0xfe41ef CLSHandler + 17564143
4 ?????? 0xfee787 __CLSExceptionRecord_block_invoke + 17606535
5 libdispatch.dylib 0x3a3f47a7 _dispatch_client_callout + 22
6 libdispatch.dylib 0x3a3fbac9 _dispatch_barrier_sync_f_invoke + 48
7 ?????? 0xfee189 CLSExceptionRecord + 17605001
8 ?????? 0xfedba3 CLSTerminateHandler() + 17603491
9 libc++abi.dylib 0x397cdde3 std::__terminate(void (*)()) + 78
10 libc++abi.dylib 0x397cd8af __cxa_rethrow + 102
11 libobjc.A.dylib 0x39e94dd3 objc_exception_rethrow + 42
12 CoreFoundation 0x2c5ec45d CFRunLoopRunSpecific + 632
13 CoreFoundation 0x2c5ec1d3 CFRunLoopRunInMode + 106
14 GraphicsServices 0x339ea0a9 GSEventRunModal + 136
15 UIKit 0x2fbfa7b1 UIApplicationMain + 1440
16 ?????? 0xefea7 main (main.m:14)
17 libdyld.dylib 0x3a414aaf start + 2
RLMRealm notification listener
0 libsystem_kernel.dylib 0x3a4caa18 kevent + 24
1 Realm 0x17aea25 realm::_impl::ExternalCommitHelper::listen() (external_commit_helper.cpp:200)
2 Realm 0x17aed0b std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0>::operator()() (external_commit_helper.cpp:159)
3 Realm 0x17aec23 std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >::__execute() (future:1026)
4 Realm 0x17aeeaf std::__1::__thread_proxy<std::__1::tuple<void (std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >::*)(), std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >*> >(void*, void*) (__functional_base:383)
5 libsystem_pthread.dylib 0x3a557e93 _pthread_body + 138
6 libsystem_pthread.dylib 0x3a557e07 _pthread_start + 118
7 libsystem_pthread.dylib 0x3a555b90 thread_start + 8
com.?????.???.realm
0 libsystem_kernel.dylib 0x3a4ca354 flock + 8
1 Realm 0x1880891 realm::util::File::lock(bool, bool) + 124
2 Realm 0x1948f1f realm::SharedGroup::do_begin_write() + 118
3 Realm 0x1877c61 auto realm::_impl::transaction::begin(realm::SharedGroup&, realm::BindingContext*, bool)::$_1::operator()<(anonymous namespace)::TransactLogValidator>((anonymous namespace)::TransactLogValidator&&) const (group_shared.hpp:965)
4 Realm 0x1872805 realm::_impl::transaction::begin(realm::SharedGroup&, realm::BindingContext*, bool) (vector:449)
5 Realm 0x18704ed realm::Realm::begin_transaction() (shared_realm.cpp:348)
6 Realm 0x185d083 -[RLMRealm beginWriteTransaction] (RLMRealm.mm:475)
7 ?????? 0xab44b __54-[BKLResourceViewLogManager updateResourceLogSuccess:]_block_invoke (BKLResourceViewLogManager.m:149)
8 libdispatch.dylib 0x3a3f47bb _dispatch_call_block_and_release + 10
9 libdispatch.dylib 0x3a3fc5b1 _dispatch_queue_drain + 952
10 libdispatch.dylib 0x3a3f6f85 _dispatch_queue_invoke + 84
11 libdispatch.dylib 0x3a3fdb9b _dispatch_root_queue_drain + 338
12 libdispatch.dylib 0x3a3fecd7 _dispatch_worker_thread3 + 94
13 libsystem_pthread.dylib 0x3a555e31 _pthread_wqthread + 668
14 libsystem_pthread.dylib 0x3a555b84 start_wqthread + 8
Steps 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.
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.
Is it possible to trace backwards? I mean find out which line of code sends this message Cannot create asynchronous query while in a write transaction and then write a stable demo to reproduce it. I may fix the problems in my code by comparing the demo with my code.
Here’s my code in thread com.?????.???.realm.
Thanks!
- (void)updateResourceLogSuccess:(NSArray<BKLResourceViewLogRO *> *)results {
[self changeLogs:results toStatus:BKLResourceViewLogROFinish];
RLMResults<BKLResourceViewLogRO *> *finishResults = [BKLResourceViewLogRO objectsWhere:@"status = %ld", BKLResourceViewLogROFinish];
if (finishResults.count > 0) {
[[RLMRealm defaultRealm] transactionWithBlock:^{
[[RLMRealm defaultRealm] deleteObjects:finishResults];
}];
}
}
- (void)changeLogs:(NSArray<BKLResourceViewLogRO *> *)logs
toStatus:(BKLResourceViewLogROStatus)status {
if (logs.count == 0) {
return;
}
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
for (BKLResourceViewLogRO *log in logs) {
if (log.invalidated) {
NSAssert(log.invalidated, @"Oops!");
[realm cancelWriteTransaction];
return;
}
log.status = status;
}
[realm commitWriteTransaction];
}
Version of Realm and Tooling
ProductName: Mac OS X
ProductVersion: 10.12
BuildVersion: 16A323
/Applications/Xcode.app/Contents/Developer
Xcode 8.0
Build version 8A218a
/usr/local/bin/pod
1.0.1
/bin/bash
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
/usr/local/bin/carthage
0.18
github "realm/realm-cocoa" "v2.0.2"
/usr/bin/git
git version 2.8.4 (Apple Git-73)
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 3
- Comments: 22 (6 by maintainers)
Oh. My bad! I fixed it by storing realm in a local variable. Thanks!
Edit: I wrote this function in my Realm extension to handle this better:
This exception is thrown when adding a notification block from within a write transaction. Do you call
addNotificationBlock()from anywhere in your code?by the way, I have reproduced our problem and cannot find the reason. realm inWriteTransaction returns NO just before beginTransaction, but than it fails with exception and realm inWriteTransaction in that moment returns YES. And there is no other threads with realm write transactions in that moment
I solved this.
Hello Guys, I recently experimented this issue after update Realm, and I figured out I was posting a notification: NotificationCenter.default.post(name: “notificationName”, object: nil) just withing a notification block, and here was my code:
and, I was subscribed to hear that notification in order to make a query of the same kind of objects being updated. I removed that bunch of code and the issue was solved. I hope this can help you.