FileDocCategorySizeDatePackage
OfflineLockManager.javaAPI DocExample6350Mon Nov 24 10:04:50 GMT 2003com.oreilly.patterns.chapter10

OfflineLockManager

public class OfflineLockManager extends Object

Fields Summary
private DataSource
dataSource
private static final String
LOCK_INSERT_STMT
private static final String
LOCK_SELECT_STMT
private static final String
RELEASE_LOCK_STMT
private static final String
RELEASE_USER_LOCKS_STMT
private static final String
RELEASE_AGED_LOCKS_STMT
Constructors Summary
public OfflineLockManager(DataSource ds)


    
   dataSource = ds;
 
Methods Summary
public booleangetLock(java.lang.String objectType, long key, java.lang.String username)


     Connection con = null;
     PreparedStatement pstmt = null;
     boolean gotLock = false;

     try {
       con = dataSource.getConnection();
       // use strict isolation
       con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
       con.setAutoCommit(false);
       pstmt = con.prepareStatement(LOCK_INSERT_STMT);
       pstmt.setString(1, objectType);
       pstmt.setLong(2, key);
       pstmt.setString(3, username);

       try {
          pstmt.executeUpdate();
          gotLock = true;
       } catch (SQLException ex) {
       } // a SQLException means a PK violation, which means an existing lock

       if (!gotLock) { 
          // This means there was a Primary Key violation: somebody has a lock!
          String lockingUsername = getLockingUser(con, objectType, key);
          if ((lockingUsername != null) && (lockingUsername.equals(username)))
             gotLock = true; // We already have a lock!
       }

       con.commit(); // end the transaction
     } catch (SQLException e) {
       try {
         con.rollback();
       } catch (SQLException ignored) {}
       LockingException le = new LockingException(e.getMessage());
       le.initCause(e); // JDK 1.4; comment out for earlier JDK releases
       throw le;
     } finally {
        if (pstmt != null) 
            try { pstmt.close(); } catch (SQLException ignored) {}
        if (con != null) 
            try { con.close(); } catch (SQLException ignored) {}
     }

     return gotLock;
 
private java.lang.StringgetLockingUser(java.sql.Connection con, java.lang.String objectType, long key)
Returns the user currently hold a lock on this type/key pair, or null if there is no lock.

    PreparedStatement pstmt = null;
    try {
      pstmt = con.prepareStatement(LOCK_SELECT_STMT);
      pstmt.setString(1, objectType);
      pstmt.setLong(2, key);
      ResultSet rs = pstmt.executeQuery();
      String lockingUser = null;
      if (rs.next())
        lockingUser = rs.getString("USERNAME");
        rs.close();
        return lockingUser;
    } catch (SQLException e) {
      throw e;
    } finally {
      if (pstmt != null) 
          try { pstmt.close(); } catch (SQLException ignored) {}
    }
 
public booleanreleaseAgedLocks()
Release all locks over 15 minutes old.

   Connection con = null;
   PreparedStatement pstmt = null;

   try {
      con = dataSource.getConnection();
      pstmt = con.prepareStatement(RELEASE_AGED_LOCKS_STMT);
      int count = pstmt.executeUpdate();
      return (count > 0); // if we deleted anything, we released locks.
   } catch (SQLException e) {
      LockingException le = new LockingException(e.getMessage());
      le.initCause(e); // JDK 1.4; comment out for earlier JDK releases
      throw le;
   } finally {
      if (pstmt != null) 
          try { pstmt.close(); } catch (SQLException ignored) {}
      if (con != null) 
          try {  con.close(); } catch (SQLException ignored) {}
   }
 
public booleanreleaseLock(java.lang.String objectType, long key, java.lang.String username)
Release a lock held by a given user on a particular type/key pair.

   Connection con = null;
   PreparedStatement pstmt = null;
   try {
     con = dataSource.getConnection();
     pstmt = con.prepareStatement(RELEASE_LOCK_STMT);
     pstmt.setString(1, objectType);
     pstmt.setLong(2, key);
     pstmt.setString(3, username);
     int count = pstmt.executeUpdate();
     return (count > 0); // if we deleted anything, we released a lock.
   } catch (SQLException e) {
     LockingException le = new LockingException(e.getMessage());
     le.initCause(e); // JDK 1.4; comment out for earlier JDK releases
     throw le;
   } finally {
     if (pstmt != null) 
         try { pstmt.close(); } catch (SQLException ignored) {}
     if (con != null) 
         try { con.close(); } catch (SQLException ignored) {}
   }
 
public booleanreleaseUserLocks(java.lang.String username)
Release all locks held by a particular user. Returns true if locks were release.

   Connection con = null;
   PreparedStatement pstmt = null;
   try {
     con = dataSource.getConnection();
     pstmt = con.prepareStatement(RELEASE_USER_LOCKS_STMT);
     pstmt.setString(1, username);
     int count = pstmt.executeUpdate();
     return (count > 0); // if we deleted anything, we released locks.
   } catch (SQLException e) {
     LockingException le = new LockingException(e.getMessage());
     le.initCause(e); // JDK 1.4; comment out for earlier JDK releases
     throw le;
   } finally {
     if (pstmt != null) 
         try { pstmt.close(); } catch (SQLException ignored) {}
     if (con != null) 
         try { con.close(); } catch (SQLException ignored) {}
   }