pushtorefresh / storio

Reactive API for SQLiteDatabase and ContentResolver.
Apache License 2.0
2.55k stars 182 forks source link

Nested transactions cause ConcurrentModificationException #495

Closed wontondon closed 9 years ago

wontondon commented 9 years ago

I ran into an issue with nested transactions in a custom PutResolver throwing a ConcurrentModificationException in DefaultStorIOSQLite.notifyAboutPendingChangesIfNotInTransaction. I was trying to ensure one entity was created successfully, so I could store its id in another entity.

private void notifyAboutPendingChangesIfNotInTransaction() {
            if (numberOfRunningTransactions == 0) {
                for (Changes changes : pendingChanges) {
                    pendingChanges.remove(changes);  // when more than one pending change you get ConcurrentModificationException
                    changesBus.onNext(changes);
                }
            }
        }

Here's an sample of the PutResolver I created using your example TweetWithUserPutResolver.

public PutResult performPut(@NonNull StorIOSQLite storIOSQLite, @NonNull TweetWithUser tweetWithUser) {
        storIOSQLite.internal().beginTransaction()
        try {
        // add user first
        final PutResults<Object> putResults = storIOSQLite
                .put()
                .object(tweetWithUser.user())
                .prepare() // BTW: it will use transaction!
                .executeAsBlocking();
       tweetWithUser.tweet.setAuthor(putResults.getId())
       storIOSQLite
                .put()
                .object(tweetWithUser.tweet())
                .prepare() // BTW: it will use transaction!
                .executeAsBlocking();

        final Set<String> affectedTables = new HashSet<String>(2);

        affectedTables.add(TweetsTable.TABLE);
        affectedTables.add(UsersTable.TABLE);

        storIOSQLite.internal().setTransactionSuccessful();

        return PutResult.newUpdateResult(2, affectedTables);
        }
        finally {
            storIOSQLite.internal().endTransaction()
        }

    }
wontondon commented 9 years ago

You can disregard this. I was using an old version of StorIO (v1.0.0). Sorry about that.

artem-zinnatullin commented 9 years ago

No problems :)