1 8 9 package com.sleepycat.je.txn; 10 11 import java.util.Collections ; 12 import java.util.HashMap ; 13 import java.util.HashSet ; 14 import java.util.Iterator ; 15 import java.util.Map ; 16 import java.util.Set ; 17 18 import javax.transaction.xa.Xid ; 19 20 import com.sleepycat.je.DatabaseException; 21 import com.sleepycat.je.LockStats; 22 import com.sleepycat.je.StatsConfig; 23 import com.sleepycat.je.Transaction; 24 import com.sleepycat.je.TransactionConfig; 25 import com.sleepycat.je.TransactionStats; 26 import com.sleepycat.je.dbi.EnvironmentImpl; 27 import com.sleepycat.je.dbi.MemoryBudget; 28 import com.sleepycat.je.latch.Latch; 29 import com.sleepycat.je.latch.LatchSupport; 30 import com.sleepycat.je.utilint.DbLsn; 31 32 36 public class TxnManager { 37 38 42 static final long NULL_TXN_ID = -1; 43 private static final String DEBUG_NAME = TxnManager.class.getName(); 44 45 private LockManager lockManager; 46 private EnvironmentImpl env; 47 private Latch allTxnLatch; 48 private Set allTxns; 49 50 private Map allXATxns; 51 52 private Map thread2Txn; 53 private long lastUsedTxnId; 54 private int nActiveSerializable; 55 56 57 private int numCommits; 58 private int numAborts; 59 private int numXAPrepares; 60 private int numXACommits; 61 private int numXAAborts; 62 63 public TxnManager(EnvironmentImpl env) 64 throws DatabaseException { 65 66 if (EnvironmentImpl.getFairLatches()) { 67 lockManager = new LatchedLockManager(env); 68 } else { 69 if (env.isNoLocking()) { 70 lockManager = new DummyLockManager(env); 71 } else { 72 lockManager = new SyncedLockManager(env); 73 } 74 } 75 76 this.env = env; 77 allTxns = new HashSet (); 78 allTxnLatch = LatchSupport.makeLatch(DEBUG_NAME, env); 79 allXATxns = Collections.synchronizedMap(new HashMap ()); 80 thread2Txn = Collections.synchronizedMap(new HashMap ()); 81 82 numCommits = 0; 83 numAborts = 0; 84 numXAPrepares = 0; 85 numXACommits = 0; 86 numXAAborts = 0; 87 lastUsedTxnId = 0; 88 } 89 90 93 synchronized public void setLastTxnId(long lastId) { 94 this.lastUsedTxnId = lastId; 95 } 96 97 100 public synchronized long getLastTxnId() { 101 return lastUsedTxnId; 102 } 103 104 107 synchronized long incTxnId() { 108 return ++lastUsedTxnId; 109 } 110 111 117 public Txn txnBegin(Transaction parent, TransactionConfig txnConfig) 118 throws DatabaseException { 119 120 if (parent != null) { 121 throw new DatabaseException 122 ("Nested transactions are not supported yet."); 123 } 124 125 return new Txn(env, txnConfig); 126 } 127 128 131 public LockManager getLockManager() { 132 return lockManager; 133 } 134 135 138 void registerTxn(Txn txn) 139 throws DatabaseException { 140 141 allTxnLatch.acquire(); 142 allTxns.add(txn); 143 if (txn.isSerializableIsolation()) { 144 nActiveSerializable++; 145 } 146 allTxnLatch.release(); 147 } 148 149 152 void unRegisterTxn(Txn txn, boolean isCommit) 153 throws DatabaseException { 154 155 allTxnLatch.acquire(); 156 try { 157 allTxns.remove(txn); 158 159 env.getMemoryBudget(). 160 updateMiscMemoryUsage(txn.getAccumulatedDelta() - 161 txn.getInMemorySize()); 162 if (isCommit) { 163 numCommits++; 164 } else { 165 numAborts++; 166 } 167 if (txn.isSerializableIsolation()) { 168 nActiveSerializable--; 169 } 170 } finally { 171 allTxnLatch.release(); 172 } 173 } 174 175 178 public void registerXATxn(Xid xid, Txn txn, boolean isPrepare) 179 throws DatabaseException { 180 181 if (!allXATxns.containsKey(xid)) { 182 allXATxns.put(xid, txn); 183 env.getMemoryBudget().updateMiscMemoryUsage 184 (MemoryBudget.HASHMAP_ENTRY_OVERHEAD); 185 } 186 187 if (isPrepare) { 188 numXAPrepares++; 189 } 190 } 191 192 195 void unRegisterXATxn(Xid xid, boolean isCommit) 196 throws DatabaseException { 197 198 if (allXATxns.remove(xid) == null) { 199 throw new DatabaseException 200 ("XA Transaction " + xid + 201 " can not be unregistered."); 202 } 203 env.getMemoryBudget().updateMiscMemoryUsage 204 (0 - MemoryBudget.HASHMAP_ENTRY_OVERHEAD); 205 if (isCommit) { 206 numXACommits++; 207 } else { 208 numXAAborts++; 209 } 210 } 211 212 215 public Txn getTxnFromXid(Xid xid) 216 throws DatabaseException { 217 218 return (Txn) allXATxns.get(xid); 219 } 220 221 224 public void setTxnForThread(Transaction txn) { 225 226 Thread curThread = Thread.currentThread(); 227 thread2Txn.put(curThread, txn); 228 } 229 230 233 public Transaction unsetTxnForThread() 234 throws DatabaseException { 235 236 Thread curThread = Thread.currentThread(); 237 return (Transaction) thread2Txn.remove(curThread); 238 } 239 240 243 public Transaction getTxnForThread() 244 throws DatabaseException { 245 246 return (Transaction) thread2Txn.get(Thread.currentThread()); 247 } 248 249 public Xid [] XARecover() 250 throws DatabaseException { 251 252 Set xidSet = allXATxns.keySet(); 253 Xid [] ret = new Xid [xidSet.size()]; 254 ret = (Xid []) xidSet.toArray(ret); 255 256 return ret; 257 } 258 259 265 public boolean 266 areOtherSerializableTransactionsActive(Locker excludeLocker) { 267 int exclude = 268 (excludeLocker != null && 269 excludeLocker.isSerializableIsolation()) ? 270 1 : 0; 271 return (nActiveSerializable - exclude > 0); 272 } 273 274 277 public long getFirstActiveLsn() 278 throws DatabaseException { 279 280 284 long firstActive = DbLsn.NULL_LSN; 285 allTxnLatch.acquire(); 286 try { 287 Iterator iter = allTxns.iterator(); 288 while(iter.hasNext()) { 289 long txnFirstActive = ((Txn) iter.next()).getFirstActiveLsn(); 290 if (firstActive == DbLsn.NULL_LSN) { 291 firstActive = txnFirstActive; 292 } else if (txnFirstActive != DbLsn.NULL_LSN) { 293 if (DbLsn.compareTo(txnFirstActive, firstActive) < 0) { 294 firstActive = txnFirstActive; 295 } 296 } 297 } 298 } finally { 299 allTxnLatch.release(); 300 } 301 return firstActive; 302 } 303 304 307 308 311 public TransactionStats txnStat(StatsConfig config) 312 throws DatabaseException { 313 314 TransactionStats stats = new TransactionStats(); 315 allTxnLatch.acquire(); 316 try { 317 stats.setNCommits(numCommits); 318 stats.setNAborts(numAborts); 319 stats.setNXAPrepares(numXAPrepares); 320 stats.setNXACommits(numXACommits); 321 stats.setNXAAborts(numXAAborts); 322 stats.setNActive(allTxns.size()); 323 TransactionStats.Active[] activeSet = 324 new TransactionStats.Active[stats.getNActive()]; 325 stats.setActiveTxns(activeSet); 326 Iterator iter = allTxns.iterator(); 327 int i = 0; 328 while (iter.hasNext()) { 329 Locker txn = (Locker) iter.next(); 330 activeSet[i] = new TransactionStats.Active 331 (txn.toString(), txn.getId(), 0); 332 i++; 333 } 334 if (config.getClear()) { 335 numCommits = 0; 336 numAborts = 0; 337 numXACommits = 0; 338 numXAAborts = 0; 339 } 340 } finally { 341 allTxnLatch.release(); 342 } 343 return stats; 344 } 345 346 349 public LockStats lockStat(StatsConfig config) 350 throws DatabaseException { 351 352 return lockManager.lockStat(config); 353 } 354 } 355 | Popular Tags |