log.info("Removing ref: " + ref);
   public void removeReference(long channelID, MessageReference ref, Transaction tx) throws Exception   {            if (tx != null)      {         //In a tx so we just add the ref in the tx in memory for now         TransactionCallback callback = getCallback(tx);         callback.addReferenceToRemove(channelID, ref);      }      else      {                  //No tx so we remove the reference directly from the db                  TransactionWrapper wrap = new TransactionWrapper();                  PreparedStatement psReference = null;         PreparedStatement psUpdate = null;         PreparedStatement psMessage = null;                  Connection conn = ds.getConnection();                  Message m = ref.getMessage();                           try         {            //get lock on message            LockMap.instance.obtainLock(m);                                          psReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));                        log.info("Removing ref " + ref + " from channel " + channelID);                        //Remove the message reference            removeReference(channelID, ref, psReference);                        int rows = psReference.executeUpdate();                        if (rows != 1)            {               throw new IllegalStateException("Failed to remove row for: " + ref);            }                        if (trace) { log.trace("Deleted " + rows + " rows"); }                        //Update the messages channel count                        psUpdate = conn.prepareStatement(getSQLStatement("DEC_CHANNELCOUNT"));                        decrementChannelCount(m, psUpdate);                        rows = psUpdate.executeUpdate();                        if (trace) { log.trace("Updated " + rows + " rows"); }                         //Delete the message (if necessary)                        psMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));                        removeMessage(m, psMessage);                                   rows = psMessage.executeUpdate();                        if (trace) { log.trace("Delete " + rows + " rows"); }                                    }         catch (Exception e)         {            wrap.exceptionOccurred();            throw e;         }         finally         {            if (psReference != null)            {               try               {                  psReference.close();               }               catch (Throwable t)               {               }            }            if (psUpdate != null)            {               try               {                  psUpdate.close();               }               catch (Throwable t)               {               }            }            if (psMessage != null)            {               try               {                  psMessage.close();               }               catch (Throwable t)               {               }            }            if (conn != null)            {               try               {                  conn.close();               }               catch (Throwable t)               {               }            }            try            {               wrap.end();                           }            finally            {                     //release the lock               LockMap.instance.releaseLock(m);            }         }            }   }