Skip to content
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

The Realm is already in a write transaction #6834

Open
feidaZhang opened this issue Aug 13, 2024 · 7 comments
Open

The Realm is already in a write transaction #6834

feidaZhang opened this issue Aug 13, 2024 · 7 comments

Comments

@feidaZhang
Copy link

How frequently does the bug occur?

Sometimes

Description

context

We found the issue in realm 10.15.0 and react-native 0.66.3 one year ago.
After we upgrade realm to 12.6.2 and react-native to 0.72.12. We still can get these exceptions from logs in production.
However, we can not repro it on our side. It's too bad.
We call the following method in a loop. I am not sure if it causes the issue.

public static saveTransaction(entity) {
    try {
      RealmManager.getRealmInstance().write(() => {
        RealmManager.getRealmInstance().create('Transaction', entity, UpdateMode.All);
      });
      return true;
    } catch (exception) {
      return false;
    }
  }

errors on iOS 17.5.1

The exceptions happen frequently to the user, who is on iOS 17.5.1.
realm_error_ios

image

errors on other users

issue: The Realm is already in a write transaction
Also, there are a few error logs and they are all instantaneous in other Android and iOS users.
image

Stacktrace & log output

No response

Can you reproduce the bug?

No

Reproduction Steps

No response

Version

12.6.2

What services are you using?

Local Database only

Are you using encryption?

No

Platform OS and version(s)

iOS 17.5.1

Build environment

Which debugger for React Native: ..

Cocoapods version

No response

Copy link

sync-by-unito bot commented Aug 13, 2024

➤ PM Bot commented:

Jira ticket: RJS-2882

@kneth
Copy link
Contributor

kneth commented Aug 13, 2024

It is difficult to tell as the functionality of RealmManager.getRealmInstance() is unknown. My guess is that the method returns a cached Realm instance which is already in a write transaction.

Instead of write(), you can use manual transactions: Realm.isInTransaction(), Realm.beginTransaction(), Realm.commitTransaction(), and Realm.cancelTransaction().

@sync-by-unito sync-by-unito bot added the Waiting-For-Reporter Waiting for more information from the reporter before we can proceed label Aug 13, 2024
@feidaZhang
Copy link
Author

feidaZhang commented Aug 15, 2024

Yes. We have a cached realm singleton globally. However, this instance will not be modified after it is created.
All our business operations run on the JS thread of RN, why does this still cause this problem? @kneth
and, may i know the difference between write() and beginTransaction(), commitTransaction() ? because we always use the write().

let realm: Realm;
export default class RealmManager {
  static getRealmInstance = () => {
    return realm;
  };
}

@github-actions github-actions bot added Needs-Attention Reporter has responded. Review comment. and removed Waiting-For-Reporter Waiting for more information from the reporter before we can proceed labels Aug 15, 2024
@kneth
Copy link
Contributor

kneth commented Aug 15, 2024

You could try to write your method to:

public static saveTransaction(entity) {
    const realm = RealmManager.getRealmInstance();
    let inTransaction = realm.isInTransaction;
    if (!inTransaction) {
      realm.beginTransaction();
    }
    realm.create('Transaction', entity, UpdateMode.All);
    if (!inTransaction) {
      realm.commitTransaction();
    }
  }

@sync-by-unito sync-by-unito bot added Waiting-For-Reporter Waiting for more information from the reporter before we can proceed and removed Needs-Attention Reporter has responded. Review comment. labels Aug 15, 2024
@feidaZhang
Copy link
Author

You could try to write your method to:

public static saveTransaction(entity) {
    const realm = RealmManager.getRealmInstance();
    let inTransaction = realm.isInTransaction;
    if (!inTransaction) {
      realm.beginTransaction();
    }
    realm.create('Transaction', entity, UpdateMode.All);
    if (!inTransaction) {
      realm.commitTransaction();
    }
  }

Do you mean we are able to reuse the current transaction?

@github-actions github-actions bot added Needs-Attention Reporter has responded. Review comment. and removed Waiting-For-Reporter Waiting for more information from the reporter before we can proceed labels Aug 15, 2024
@feidaZhang
Copy link
Author

and, Is this error related to memory collecting failure?
We got the error logs that were thrown from write().
memory

@kneth
Copy link
Contributor

kneth commented Aug 15, 2024

mmap() failed: Cannot allocate memory ... - it sounds like you have a transaction which is too large to handle for the database. Can you split it multiple transactions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants