[BUG] Calling store.get() in RoomDatabase.withTransaction will encounter a deadlock
Describe the bug
When I call store.get() in the RoomDatabase.withTransaction {} and the store trigger the writer to write data into the database, a deadlock will occur. Everything is fine if the writer does not trigger or calling the store.get() outside the withTransaction {}.
To Reproduce
- clear the Room's table that the Store used
- call
store.get()inside theRoomDatabase.withTransaction {}
Sample code (Full sample):
viewLifecycleOwner.lifecycleScope.launch {
appDatabase.forumDao().deleteAll()
// The transaction work fine if uncomment the line below
// forumStore.get(ForumKey(id = "1"))
appDatabase.withTransaction {
Log.d("TEST", "Start transaction")
forumStore.get(ForumKey(id = "1"))
Log.d("TEST", "End transaction")
}
}
Expected behavior
- According to the sample above, either the "End transaction" should print or the error log should appear
Smartphone (please complete the following information):
- Device: Emulator Pixel_4_API_33
- OS: Android 13
- Store Version: 4.0.5
Thank you for reporting and including a sample ❤️. I can take a look this week and let you know a fix/suggestion. My initial thinking is the transaction is locking writing to the db within your block. Without writing we can't read.
This looks related. https://issuetracker.google.com/issues/120854786 Seems like there is a runInTransaction function when working with suspend and transactions in room
Do you mind trying the new transaction api and reporting back if it works?
Thanks for your fast reply. The runInTransaction() can't support suspend function, so it can't replace withTransaction(). Besides, the withTransaction() is the new API introduced in the issue you posted above.
I find out that the KDoc of withTransaction() has mentioned that it should use the same coroutineScope that receive by the suspending block to perform blocking database operation. So I guess it's the limitation of Room which let the usage of Store inside withTransaction() impossible.
I'm going to keep this issue open as we are currently rewriting some store internals for a Store5 major release. Let me think about how to solve this in a generic manner.