diff --git a/utils/src/com/cloud/utils/db/Merovingian2.java b/utils/src/com/cloud/utils/db/Merovingian2.java index 61aeb6a104f..5abcdec1ae8 100644 --- a/utils/src/com/cloud/utils/db/Merovingian2.java +++ b/utils/src/com/cloud/utils/db/Merovingian2.java @@ -44,7 +44,7 @@ import com.cloud.utils.time.InaccurateClock; public class Merovingian2 extends StandardMBean implements MerovingianMBean { private static final Logger s_logger = Logger.getLogger(Merovingian2.class); - + private static final String ACQUIRE_SQL = "INSERT INTO op_lock (op_lock.key, op_lock.mac, op_lock.ip, op_lock.thread, op_lock.acquired_on, waiters) VALUES (?, ?, ?, ?, ?, 1)"; private static final String INCREMENT_SQL = "UPDATE op_lock SET waiters=waiters+1 where op_lock.key=? AND op_lock.mac=? AND op_lock.ip=? AND op_lock.thread=?"; private static final String SELECT_SQL = "SELECT op_lock.key, mac, ip, thread, acquired_on, waiters FROM op_lock"; @@ -56,15 +56,15 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { private static final String SELECT_MGMT_LOCKS_SQL = SELECT_SQL + " WHERE mac=?"; private static final String SELECT_THREAD_LOCKS_SQL = SELECT_SQL + " WHERE mac=? AND ip=?"; private static final String CLEANUP_THREAD_LOCKS_SQL = "DELETE FROM op_lock WHERE mac=? AND ip=? AND thread=?"; - + TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT"); - - private long _msId; - + + private final long _msId; + private static Merovingian2 s_instance = null; ScheduledExecutorService _executor = null; Connection _conn = null; - + private Merovingian2(long msId) { super(MerovingianMBean.class, false); _msId = msId; @@ -73,7 +73,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { throw new CloudRuntimeException("Unable to initialize a connection to the database for locking purposes due to " + result); } } - + public static synchronized Merovingian2 createLockMaster(long msId) { assert s_instance == null : "No lock can serve two masters. Either he will hate the one and love the other, or he will be devoted to the one and despise the other."; s_instance = new Merovingian2(msId); @@ -85,11 +85,11 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { } return s_instance; } - + public static Merovingian2 getLockMaster() { return s_instance; } - + @Override public String resetDbConnection() { s_logger.info("Resetting the database connection for locks"); @@ -100,19 +100,20 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { s_logger.error("Unable to close connection", th); } } - + try { _conn = Transaction.getStandaloneConnectionWithException(); _conn.setAutoCommit(true); + _conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); } catch (SQLException e) { s_logger.error("Unable to get a new db connection", e); return "Unable to initialize a connection to the database for locking purposes: " + e; } - + if (_conn == null) { return "Unable to initialize a connection to the database for locking purposes, shutdown this server!"; } - + if (_executor != null) { try { _executor.shutdown(); @@ -120,18 +121,18 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { s_logger.error("Unable to shutdown the executor", th); } } - + _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("LockMasterConnectionKeepAlive")); _executor.schedule(new KeepAliveTask(), 10, TimeUnit.SECONDS); - + return "Success"; } - + public boolean acquire(String key, int timeInSeconds) { Thread th = Thread.currentThread(); String threadName = th.getName(); int threadId = System.identityHashCode(th); - + if (s_logger.isTraceEnabled()) { s_logger.trace("Acquiring lck-" + key + " with wait time of " + timeInSeconds); } @@ -157,7 +158,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { } return false; } - + protected boolean increment(String key, String threadName, int threadId) { PreparedStatement pstmt = null; try { @@ -183,7 +184,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { } } } - + protected boolean doAcquire(String key, String threadName, int threadId) { PreparedStatement pstmt = null; @@ -218,11 +219,11 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { } catch (SQLException e) { } } - + s_logger.trace("Unable to acquire lck-" + key); return false; } - + protected Map isLocked(String key) { PreparedStatement pstmt = null; ResultSet rs = null; @@ -233,7 +234,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { if (!rs.next()) { return null; } - + return toLock(rs); } catch (SQLException e) { throw new CloudRuntimeException("SQL Exception on inquiry", e); @@ -250,7 +251,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { } } } - + public void cleanupThisServer() { cleanupForServer(_msId); } @@ -275,7 +276,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { } } } - + public boolean release(String key) { PreparedStatement pstmt = null; Thread th = Thread.currentThread(); @@ -314,7 +315,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { } } } - + protected Map toLock(ResultSet rs) throws SQLException { Map map = new HashMap(); map.put("key", rs.getString(1)); @@ -324,9 +325,9 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { map.put("date", rs.getString(5)); map.put("count", Integer.toString(rs.getInt(6))); return map; - + } - + protected List> toLocks(ResultSet rs) throws SQLException { LinkedList> results = new LinkedList>(); while (rs.next()) { @@ -334,7 +335,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { } return results; } - + protected List> getLocks(String sql, Long msId) { PreparedStatement pstmt = null; ResultSet rs = null; @@ -369,7 +370,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { public List> getLocksAcquiredByThisServer() { return getLocks(SELECT_MGMT_LOCKS_SQL, _msId); } - + public int owns(String key) { Thread th = Thread.currentThread(); int threadId = System.identityHashCode(th); @@ -382,7 +383,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { } return -1; } - + public List> getLocksAcquiredBy(long msId, String threadName) { PreparedStatement pstmt = null; ResultSet rs = null; @@ -406,12 +407,12 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { } } } - + public void cleanupThread() { Thread th = Thread.currentThread(); String threadName = th.getName(); int threadId = System.identityHashCode(th); - + PreparedStatement pstmt = null; try { pstmt = _conn.prepareStatement(CLEANUP_THREAD_LOCKS_SQL); @@ -431,7 +432,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { } } } - + @Override public boolean releaseLockAsLastResortAndIReallyKnowWhatIAmDoing(String key) { s_logger.info("Releasing a lock from jMX lck-" + key);