| 1 21 22 package com.rift.coad.daemon.messageservice; 24 25 import java.util.Iterator ; 27 import java.util.Map ; 28 import java.util.LinkedHashMap ; 29 import java.util.HashMap ; 30 import java.util.concurrent.ConcurrentHashMap ; 31 import javax.naming.Context ; 32 import javax.naming.InitialContext ; 33 import javax.transaction.xa.XAException ; 34 import javax.transaction.xa.XAResource ; 35 import javax.transaction.xa.Xid ; 36 37 import org.apache.log4j.Logger; 39 40 import com.rift.coad.util.transaction.TransactionManager; 42 43 44 50 public class IDLock implements XAResource { 51 52 55 public class Lock { 56 57 private String id = null; 59 private Xid owner = null; 60 private int referenceCount = 0; 61 62 65 public Lock(String id) { 66 this.id = id; 67 } 68 69 70 75 public String getId() { 76 return id; 77 } 78 79 80 85 public synchronized int incrementReferenceCount() { 86 return ++referenceCount; 87 } 88 89 90 96 public synchronized int decrementReferenceCount() { 97 return --referenceCount; 98 } 99 100 101 108 public synchronized void lock(Xid owner) throws IDLockException { 109 while (this.owner != null) { 110 try { 111 wait(); 112 } catch (Exception ex) { 113 log.error("Failed to lock this object : " + ex.getMessage(), 114 ex); 115 throw new IDLockException( 116 "Failed to lock this object : " + ex.getMessage(), 117 ex); 118 } 119 } 120 this.owner = owner; 121 } 122 123 124 127 public synchronized void unlock() { 128 this.owner = null; 129 notify(); 130 } 131 } 132 133 private static IDLock singleton = null; 135 136 private Logger log = Logger.getLogger(IDLock.class.getName()); 138 139 private Map transactionMap = new ConcurrentHashMap (); 141 private Map lockMap = new HashMap (); 142 private ThreadLocal currentLock = new ThreadLocal (); 143 144 145 148 private IDLock() { 149 } 150 151 152 157 public synchronized static IDLock getInstance() { 158 if (singleton == null) { 159 singleton = new IDLock(); 160 } 161 return singleton; 162 } 163 164 165 171 public void lock(String id) throws IDLockException { 172 try { 173 Lock lock = null; 174 synchronized(lockMap) { 175 lock = (Lock)lockMap.get(id); 176 if (lock == null) { 177 lock = new Lock(id); 178 lockMap.put(id,lock); 179 } 180 lock.incrementReferenceCount(); 181 } 182 currentLock.set(lock); 183 TransactionManager.getInstance().bindResource(this,false); 184 } catch (Exception ex) { 185 log.error("Failed to lock the id [" + id + "] : " + 186 ex.getMessage(),ex); 187 throw new IDLockException("Failed to lock the id [" + id + "] : " + 188 ex.getMessage(),ex); 189 } 190 } 191 192 193 201 public void commit(Xid xid, boolean b) throws XAException { 202 try { 203 Lock lock = (Lock)transactionMap.remove(xid); 204 lock.unlock(); 205 synchronized(lockMap) { 206 if (lock.decrementReferenceCount() <= 0) { 207 lockMap.remove(lock.getId()); 208 } 209 } 210 } catch (Exception ex) { 211 log.error("Failed to roll back the changes : " + 212 ex.getMessage(),ex); 213 throw new XAException ("Failed to roll back the changes : " + 214 ex.getMessage()); 215 } 216 } 217 218 219 226 public void end(Xid xid, int i) throws XAException { 227 } 228 229 230 236 public void forget(Xid xid) throws XAException { 237 try { 238 Lock lock = (Lock)transactionMap.remove(xid); 239 lock.unlock(); 240 synchronized(lockMap) { 241 if (lock.decrementReferenceCount() <= 0) { 242 lockMap.remove(lock.getId()); 243 } 244 } 245 } catch (Exception ex) { 246 log.error("Failed to roll back the changes : " + 247 ex.getMessage(),ex); 248 throw new XAException ("Failed to roll back the changes : " + 249 ex.getMessage()); 250 } 251 } 252 253 254 260 public int getTransactionTimeout() throws XAException { 261 return -1; 262 } 263 264 265 273 public boolean isSameRM(XAResource xAResource) throws XAException { 274 return this == xAResource; 275 } 276 277 278 285 public int prepare(Xid xid) throws XAException { 286 return XAResource.XA_OK; 287 } 288 289 290 298 public Xid [] recover(int i) throws XAException { 299 return null; 300 } 301 302 303 309 public void rollback(Xid xid) throws XAException { 310 try { 311 Lock lock = (Lock)transactionMap.remove(xid); 312 lock.unlock(); 313 synchronized(lockMap) { 314 if (lock.decrementReferenceCount() <= 0) { 315 lockMap.remove(lock.getId()); 316 } 317 } 318 } catch (Exception ex) { 319 log.error("Failed to roll back the changes : " + 320 ex.getMessage(),ex); 321 throw new XAException ("Failed to roll back the changes : " + 322 ex.getMessage()); 323 } 324 } 325 326 327 334 public boolean setTransactionTimeout(int i) throws XAException { 335 return true; 336 } 337 338 339 346 public void start(Xid xid, int i) throws XAException { 347 try { 348 Lock lock = (Lock)currentLock.get(); 349 lock.lock(xid); 350 transactionMap.put(xid,lock); 351 } catch (Exception ex) { 352 log.error("Failed to start the transaction : " + 353 ex.getMessage(),ex); 354 throw new XAException ("Failed to start the transaction : " + 355 ex.getMessage()); 356 } 357 } 358 359 360 361 } 362 | Popular Tags |