-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Realm already in a write transaction" Exception #4511
Comments
This is working as intended. The thing that changed is that previously the notification would have been simply discarded entirely when |
I guess I'm confused about the rules when it's safe to do a write transaction from a notification, since I am occasionally in a write transaction already or I'm not in one. I'm using the notifications to transition objects between states (e.g. for network activity) which feels like a pretty common non-UI use-case for notifications. I've ended up writing something like: extension Realm {
public func safeWrite(_ block: (() throws -> Void)) throws {
if isInWriteTransaction {
try block()
} else {
try write(block)
}
}
} Is this the right path to take? I wish the notifications would happen before the write transaction occurs, always, so I can be entirely sure the behavior that's going to happen. |
If you never cancel write transactions made on the same thread as your notification block is on then just making the changes in the existing write transaction is a reasonable way to handle it (if you do cancel writes, then the changes made in the notification block would be rolled back as well). If possible you probably want non-UI-related notifications which are making writes to be running in their own thread under your control, which would make this requirement not too bad to enforce. Sending the notifications before beginning the write transaction doesn't really work. We could implement logic like the following:
This has a few issues. It's prone to starvation if you have another thread making a steady stream of writes, since in the time it takes to calculate and send the notifications for one write transaction the other thread could have reacquired the write lock and begun another write transaction and then this thread never actually gets to do its own write. More importantly, it also runs into the problem that calling One thing we could do is make the Realm pretend it isn't a in a write transaction while calling the notification block. Essentially all it'd have to do is ignore the first call to |
I had this issue too. It must be stated in documentation that notifications may come inside write transaction and it is user's responsibility to check |
@evgeny-sureev's last comment summarizes what needs to be done to correct this issue. Check |
Is this safe? extension Realm { |
@zzdravkin did you figure it out? I just ran into the error you mentioned, even though it's inside asyncWrite |
Reported on the iOS Folks Slack, a user came across a potential regression in Realm's change notification feature.
A change notification block is created for responding to when a
Results
object changes. That block then also contains a write transaction that further modifies the data.In earlier versions of Realm, this was fine. However in the latest version of Realm, this now produces a "Realm already in a write transaction" exception.
Goals
To successfully perform a write transaction inside a change notification block.
Expected Results
The write transaction to successfully execute.
Actual Results
Terminating app due to uncaught exception 'RLMException', reason: 'The Realm is already in a write transaction'
Code Sample
The following code sample will 100% trigger the exception when executed:
A sample app demonstrating this code is also available: RealmWriteTest.zip
Version of Realm and Tooling
Realm version: Swift 2.1.2
Xcode version: 8.2
iOS/OSX version: 10.2
Dependency manager + version: CocoaPods 1.1.1
The text was updated successfully, but these errors were encountered: