From ec4a46ece3ffceff16c69c8be9256f093035edf7 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Sat, 23 Jul 2011 15:24:33 -0700 Subject: [PATCH] use in memory counter for locks so we don't do a delete everytime --- .../src/com/cloud/utils/db/Merovingian2.java | 65 +++++++++++++++---- utils/src/com/cloud/utils/db/Transaction.java | 2 +- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/utils/src/com/cloud/utils/db/Merovingian2.java b/utils/src/com/cloud/utils/db/Merovingian2.java index 37d580d71de..fe274c6bf59 100644 --- a/utils/src/com/cloud/utils/db/Merovingian2.java +++ b/utils/src/com/cloud/utils/db/Merovingian2.java @@ -59,6 +59,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { private static Merovingian2 s_instance = null; private ConnectionConcierge _concierge = null; + private static ThreadLocal s_tls = new ThreadLocal(); private Merovingian2(long msId) { super(MerovingianMBean.class, false); @@ -91,6 +92,25 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { return s_instance; } + protected void incrCount() { + Count count = s_tls.get(); + if (count == null) { + count = new Count(); + s_tls.set(count); + } + + count.count++; + } + + protected void decrCount() { + Count count = s_tls.get(); + if (count == null) { + return; + } + + count.count--; + } + public boolean acquire(String key, int timeInSeconds) { Thread th = Thread.currentThread(); String threadName = th.getName(); @@ -103,21 +123,23 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { while ((InaccurateClock.getTime() - startTime) < (timeInSeconds * 1000)) { int count = owns(key); - if (count == -1) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - } - } else if (count >= 1) { + if (count >= 1) { return increment(key, threadName, threadId); - } else { + } else if (count == 0) { if (doAcquire(key, threadName, threadId)) { return true; } } + try { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Sleeping more time while waiting for lck-" + key); + } + Thread.sleep(5000); + } catch (InterruptedException e) { + } } if (s_logger.isTraceEnabled()) { - s_logger.trace("Timed out on acquiring lock " + key); + s_logger.trace("Timed out on acquiring lock " + key + ". Waited for " + (InaccurateClock.getTime() - startTime)); } return false; } @@ -133,9 +155,13 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { int rows = pstmt.executeUpdate(); assert (rows <= 1) : "hmm...non unique key? " + pstmt; if (s_logger.isTraceEnabled()) { - s_logger.trace("lck-" + key + (rows == 1 ? " acquired for a second time" : " failed to acquire")); + s_logger.trace("lck-" + key + (rows == 1 ? " acquired again" : " failed to acquire again")); } - return rows == 1; + if (rows == 1) { + incrCount(); + return true; + } + return false; } catch (SQLException e) { throw new CloudRuntimeException("Unable to increment " + key, e); } finally { @@ -165,6 +191,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { if (s_logger.isTraceEnabled()) { s_logger.trace("Acquired for lck-" + key); } + incrCount(); return true; } } catch(SQLException e) { @@ -265,6 +292,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { if (result == 1 && s_logger.isTraceEnabled()) { s_logger.trace("lck-" + key + " removed"); } + decrCount(); } return rows == 1; } catch (SQLException e) { @@ -372,6 +400,15 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { } public void cleanupThread() { + Count count = s_tls.get(); + if (count == null || count.count == 0) { + return; + } + + int c = count.count; + + count.count = 0; + Thread th = Thread.currentThread(); String threadName = th.getName(); int threadId = System.identityHashCode(th); @@ -383,7 +420,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { pstmt.setString(2, threadName); pstmt.setInt(3, threadId); int rows = pstmt.executeUpdate(); - assert (rows == 0) : "Abandon hope, all ye who enter here....There were still " + rows + " locks not released when the transaction ended!"; + assert (false) : "Abandon hope, all ye who enter here....There were still " + rows + ":" + c + " locks not released when the transaction ended!"; } catch (SQLException e) { throw new CloudRuntimeException("Can't clear locks " + pstmt, e); } finally { @@ -398,7 +435,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { @Override public boolean releaseLockAsLastResortAndIReallyKnowWhatIAmDoing(String key) { - s_logger.info("Releasing a lock from jMX lck-" + key); + s_logger.info("Releasing a lock from JMX lck-" + key); PreparedStatement pstmt = null; try { pstmt = _concierge.conn().prepareStatement(RELEASE_LOCK_SQL); @@ -410,4 +447,8 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { return false; } } + + protected static class Count { + public int count = 0; + } } diff --git a/utils/src/com/cloud/utils/db/Transaction.java b/utils/src/com/cloud/utils/db/Transaction.java index a9442df25dd..59fd85c531f 100755 --- a/utils/src/com/cloud/utils/db/Transaction.java +++ b/utils/src/com/cloud/utils/db/Transaction.java @@ -126,7 +126,7 @@ public class Transaction { // the existing DAO features // public void transitToUserManagedConnection(Connection conn) { - assert(_conn == null && _stack.size() <= 1) : "Can't change to a user managed connection unless the stack is empty and the db connection is null: " + toString(); + assert (_conn == null) : "Can't change to a user managed connection unless the stack is empty and the db connection is null: " + toString(); _conn = conn; _dbId = CONNECTED_DB; }