Objectbox-java: java.lang.IllegalStateException: Transaction is closed

Created on 21 Jul 2020  路  7Comments  路  Source: objectbox/objectbox-java

Issue Basics

  • ObjectBox version : 2.5.1
  • Reproducibility : occasionally without visible pattern

Reproducing the bug

Description

I had this issue occasionally while inserting some data into my box. I don't at any moment close manually any transaction or something.

Code (cherry picked)

Box<Car> cars = ObjectBox.getBox().boxFor(Car.class);

JSONArray carsFromServeur = getCars();

for (int i = 0; i < carsFromServeur.length(); i++) { // length == 484
/* some code here */
put(new Car(...));
}

public void put(Car car) {
try {
cars.put(car); // <--bug here, doesn't always pass
} catch (UniqueViolationException e) {
/* some code here */
}
}

Logs & stackstraces

Fatal Exception: java.lang.IllegalStateException: Transaction is closed
at io.objectbox.Transaction.checkOpen(Transaction.java:92)
at io.objectbox.Transaction.commit(Transaction.java:133)
at io.objectbox.Transaction.commitAndClose(Transaction.java:139)
at io.objectbox.Box.commitWriter(Box.java:125)
at io.objectbox.Box.put(Box.java:333)
at xxx.put(CarsBox.java:31)

Entities

@Entity
public class Car {
@Id
private long id;
@Unique
private String uuid;
private String name;
private ToOne<User> user;
}

Misc

I am executing this as result of a http request. The same data is fetched and inserted each time.

more info required

All 7 comments

I'm seeing the possibility of UniqueViolationException - do you have any means to see if that triggers the issue?

Thank you for your quick response.

My bad, I forgot to mention an importent part of code :

public void put(Car car) {
try {
cars.put(car);
} catch (UniqueViolationException e) {
/* some code here then :*/
cars.put(aotherCar); // <--this one
}
}

OK, that's already a very good lead. I'm not sure what happens if your code would be recursive; you could restructure your code to only catch UniqueViolationException once to ensure it's OK on your side.

Can not reproduce this so far, e.g. the following works fine:

@Test
public void putAfterUniqueViolation() {
    for (int i = 0; i < 1000; i++) {
        putAfterUniqueViolationImpl(i);
    }
}

private void putAfterUniqueViolationImpl(int offset) {
    // Every other put violates unique constraint (uses previous string), the other put is successful.
    String uniqueEveryOther = "unique1" + (offset % 2 == 0 ? offset : offset - 1);
    UniqueEntity entity = new UniqueEntity(0, uniqueEveryOther, null, null);
    try {
        box.put(entity);
    } catch (UniqueViolationException e) {
        entity.uniqueString = "unique2" + offset;
        box.put(entity);
    }
}

Maybe the Transaction was closed while this code was running, e.g. the BoxStore was closed or somehow finalized from another thread?

At some point I call BoxStore.deleteAllFiles() so maybe this executes while put() is still running.

Unfortnattly I don't have much more informtion and this bug doesn't seems to happen very frequentlly so I will come back to this thread if I have more details.

Thank you

At some point I call BoxStore.deleteAllFiles() so maybe this executes while put() is still running.

Yeah, that sounds like you are up to some "adventures" :smirk: Better ensure to close the store and shutdown all threads using it before deleting DB files. You enter "undefined behavior" territory otherwise...

It's been 3 weeks without additional information. If this this occurs after after the proposed change please create a new issue with updated information. Thanks for reaching out.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chiara-jm picture chiara-jm  路  17Comments

greenrobot picture greenrobot  路  17Comments

greenrobot picture greenrobot  路  53Comments

williamwue picture williamwue  路  18Comments

Gaket picture Gaket  路  79Comments