CompletableFuture and locks

Viewed 2347

I have the original synchronous code,

Lock lock = getLock(userId); // get a lock from guava Striped locks
lock.lock();

try {
   // do some database writing action
   updateUserByUserId(userId);
   return updateUserPropertiesByUserId(userId);
}
finally {
    lock.unlock();
}

The purpose of the lock is to mimic pessimistic database locking at a higher level.

In Java8, CompleteableFutures are introduced. And updateUserByUserId(userId); and updateUserPropertiesByUserId(userId); can now return CompletableFuture<Void> for a fully async implementation.

My question is, how can I employ the same mechanism? or is this way of locking completely wrong? (I don't really want to rely on the database's locking. If possible, I want to handle this in the app layer instead of the database layer)

I have tried

Lock lock = getLock(userId); // get a lock from guava Striped locks

return CompletableFuture
        .supplyAsync(() -> {
            lock.lock();
        })
        .thenCompose(VOID -> updateUserByUserId(userId))
        .thenCompose(entity -> updateUserPropertiesByUserId(userId))
        .whenComplete((entity, ex) -> {
            lock.unlock();
        });

But I've been getting IllegalMonitorStateException on lock.unlock();, which is expected, because you're not supposed to unlock a lock in a different thread.

Any suggestions?

1 Answers
Related