Realm Kotllin: how to tell whether a Realm is "open", i.e. in a Transaction

I am converting an Android Java project written with Realm a number of years ago to the Kotlin version of Realm. I am having a lot of problems with “STATE”, for instance, I’m not allowed to “write” because a “read” is open.

When I do my Realm Config, I list all of my database object types. which I think is the intention, So when the Realm is in a “read” or “write” transaction, does that apply to all of the database object types or are there individual read/write states for each one? Is there someplace I should read that discusses this?

So, for example,. if I have a writeBlocking that is failing because of " java.lang.IllegalStateException: [RLM_ERR_WRONG_TRANSACTION_STATE]: Trying to modify database while in read transaction", how do I tell what is going on. Can I find out whether transactions are going on in the Realm that are causing this message? (Would this be on an objectType or global basis?) Are there some Realm functions I can monitor to see whether transactions are in progress? One post I saw from years ago mentioned “getGlobalInstanceCount”, but I can’t seem to find anything like that available currently.

Thanks!

Hmm, transactions should automatically detect if another is running, so not 100% sure why you are getting this message.

My guess is that you are perhaps opening multiple instances of the same file using Realm.open(). This could result in these kind of errors because the underlying file knows if another transaction is running.

If this is the case, I would recommend refactoring the code to make the Realm instance a global singleton in you app.

I had been using a global singleton (as I had done on my previous version), but then I worried that my read transactions were continuing forever until I terminated the instance, so I did switch over to just using a Realm instance as needed. But that sounds like it was a bad idea and I should switch back to a global instance.

So, after I do a query, would I typically do a close() ? After the close(), can I still read the fields of the objects I obtained in the query?

Thanks.

If you close the Realm, data will not be available unless you call copyFromRealm() before closing it. Using this API will copy all the objects into JVM memory, rather then using the native memory.

This is required due to Realms underlying architecture which we call “lazy-loading”. Basically, all objects keep a reference to fixed read-transaction and then fetch data as needed. This is also what enables you to have hundreds of thousands of elements in a query result without the app running out of memory.

We are managing these transactions under the hood for you. Releasing them as needed. Realm is an MVCC database, so you can have multiple read transactions (which we call versions), and they are all non-blocking and consistent.

So in general, you shouldn’t need to worry about your read transactions and opening and closing Realm instances. We are handling them for you. This is also why we recommend just having a single global singleton instance open for the entire lifecycle of the app.

Thanks. Can you suggest a good example program that does this properly in Realm Kotlin?

1 Like