-
Notifications
You must be signed in to change notification settings - Fork 353
Distributed Row Lock
Sagar Loke edited this page Feb 14, 2014
·
3 revisions
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).
Currently Distributed Row Lock recipe works if the CF is created with “WITH COMPACT STORAGE” (Storage pre 1.2 format).
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
- Getting-Started
- Configuration
- Features
- Monitoring
- Thread Safety
- Timeouts
- Recipes
- Examples
- Javadoc
- Utilities
- Cassandra-Compatibility
- FAQ
- End-to-End Examples
- Astyanax Integration with Java Driver