forked from Netflix/astyanax
-
Notifications
You must be signed in to change notification settings - Fork 1
Distributed Row Lock
elandau edited this page May 22, 2012
·
1 revision
The distributed row lock performs a sequence of Write-Read-Write operations to effectively lock a row. The recipe also allows for reading the entire row (the read) and committing it back as part of the release mutation (the last write).
ColumnPrefixDistributedRowLock<String> lock =
new ColumnPrefixDistributedRowLock<String>(keyspace, LOCK_CF, "RowKeyToLock")
.expireLockAfter(1, TimeUnit.SECONDS);
try {
lock.acquire();
}
catch (StaleLockException e) {
// The row contains a stale or abandoned lock
// These can either be manually clean up or automatically
// cleaned up (and ignored) by calling failOnStaleLock(false)
}
catch (BusyLockException e) {
// The row is currently locked.
}
finally {
lock.release();
}
// Take a lock
ColumnPrefixDistributedRowLock<String> lock =
new ColumnPrefixDistributedRowLock<String>(keyspace, SOME_CF, "MyRowKey")
.expireLockAfter(1, TimeUnit.SECONDS);
try {
// Take the lock while reading ALL the columns in the row
ColumnMap<String> columns = lock.acquireLockAndReadRow();
// Modify a value and add it to a batch mutation
int value = columns.get("SomeDataColumn").getIntegerValue() + 1;
MutationBatch m = keyspace.prepareMutationBatch();
m.withRow(LOCK_CF, rowKey)
.putColumn("SomeDataColumn", value, null);
// Write data AND release the lock
lock.releaseWithMutation(m);
}
catch (Exception e) {
lock.release();
}
This variation of the recipe implements a backoff and retry mechanism for busy locks. The following example will use a bounded exponential backoff with time slices of 250 msec and maximum wait time of 10,000 msec with a maximum of 10 attempts. If the lock cannot be acquired a BusyLockException will be thrown.
ColumnPrefixDistributedRowLock<String> lock =
new ColumnPrefixDistributedRowLock<String>(keyspace, LOCK_CF, "RowKeyToLock")
.withBackoff(new BoundedExponentialBackoff(250, 10000, 10))
.expireLockAfter(1, TimeUnit.SECONDS);
try {
lock.acquire();
}
catch (StaleLockException e) {
}
catch (BusyLockException e) {
}
finally {
lock.release();
}
A Netflix Original Production
Tech Blog | Twitter @NetflixOSS | Jobs