Index: hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java (revision 1495300) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java (working copy) @@ -217,8 +217,8 @@ // Members ////////////////////////////////////////////////////////////////////////////// - private final ConcurrentHashMap lockedRows = - new ConcurrentHashMap(); + private final ConcurrentHashMap lockedRows = + new ConcurrentHashMap(); private final ConcurrentHashMap lockIds = new ConcurrentHashMap(); private final AtomicInteger lockIdGenerator = new AtomicInteger(1); @@ -3199,19 +3199,22 @@ try { HashedBytes rowKey = new HashedBytes(row); CountDownLatch rowLatch = new CountDownLatch(1); + RowLockContext rowLockContext = new RowLockContext(rowLatch, Thread.currentThread().getName()); // loop until we acquire the row lock (unless !waitForLock) while (true) { - CountDownLatch existingLatch = lockedRows.putIfAbsent(rowKey, rowLatch); - if (existingLatch == null) { + RowLockContext existingContext = lockedRows.putIfAbsent(rowKey, rowLockContext); + // If the row is already locked by this same thread we acquired it + if (existingContext == null + || existingContext.threadName.equals(Thread.currentThread().getName())) { break; } else { - // row already locked + // row already locked by some other thread if (!waitForLock) { return null; } try { - if (!existingLatch.await(this.rowLockWaitDuration, + if (!existingContext.latch.await(this.rowLockWaitDuration, TimeUnit.MILLISECONDS)) { throw new IOException("Timed out on getting lock for row=" + Bytes.toStringBinary(row)); @@ -3252,13 +3255,13 @@ LOG.warn("Release unknown lockId: " + lockId); return; } - CountDownLatch rowLatch = lockedRows.remove(rowKey); - if (rowLatch == null) { + RowLockContext rowLockContext = lockedRows.remove(rowKey); + if (rowLockContext == null) { LOG.error("Releases row not locked, lockId: " + lockId + " row: " + rowKey); return; } - rowLatch.countDown(); + rowLockContext.latch.countDown(); } /** @@ -5629,4 +5632,15 @@ */ void failedBulkLoad(byte[] family, String srcPath) throws IOException; } + + static class RowLockContext { + private CountDownLatch latch; + private String threadName; + + public RowLockContext(CountDownLatch latch, String threadName) { + this.latch = latch; + this.threadName = threadName; + } + } + }