1 21 22 package org.apache.derby.impl.store.raw.xact; 23 24 import org.apache.derby.iapi.services.sanity.SanityManager; 25 import org.apache.derby.iapi.services.io.Formatable; 26 import org.apache.derby.iapi.services.io.FormatIdUtil; 27 import org.apache.derby.iapi.services.io.StoredFormatIds; 28 29 import org.apache.derby.iapi.error.StandardException; 30 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 31 import org.apache.derby.iapi.sql.conn.StatementContext; 32 import org.apache.derby.iapi.store.access.TransactionInfo; 33 import org.apache.derby.iapi.store.raw.GlobalTransactionId; 34 import org.apache.derby.iapi.store.raw.xact.TransactionId; 35 import org.apache.derby.iapi.store.raw.log.LogInstant; 36 37 import java.io.ObjectOutput ; 38 import java.io.ObjectInput ; 39 import java.io.IOException ; 40 41 53 54 public class TransactionTableEntry implements Formatable, TransactionInfo, Cloneable 55 { 56 private TransactionId xid; 59 private GlobalTransactionId gid; 60 private LogInstant firstLog; 61 private LogInstant lastLog; 62 63 private int transactionStatus; 68 69 private transient Xact myxact; 72 private transient boolean update; 73 private transient boolean recovery; private transient boolean needExclusion; 80 private boolean isClone; 83 private transient LanguageConnectionContext lcc; 84 85 86 87 static final int UPDATE = 0x1; 89 static final int RECOVERY = 0x2; 90 static final int EXCLUDE = 0x4; 91 92 TransactionTableEntry( 93 Xact xact, 94 TransactionId tid, 95 int status, 96 int attribute) 97 { 98 myxact = xact; 99 xid = tid; 100 transactionStatus = status; 101 102 update = (attribute & UPDATE) != 0; 103 needExclusion = (attribute & EXCLUDE) != 0; 104 recovery = (attribute & RECOVERY) != 0; 105 106 if (SanityManager.DEBUG) 107 { 108 SanityManager.ASSERT(tid != null, "tid is null"); 109 if (update && xact.getFirstLogInstant() == null) 110 { 111 SanityManager.THROWASSERT( 112 "update transaction has firstLog = null"); 113 } 114 115 116 124 } 125 126 if (recovery) 135 { 136 if (SanityManager.DEBUG) 138 { 139 SanityManager.ASSERT(update, "recovery but not update"); 140 141 if (tid != xact.getId()) 142 { 143 SanityManager.THROWASSERT( 144 "adding a update transaction during recovery " + 145 " but the tids doesn't match" + 146 tid + " " + xact.getId()); 147 } 148 } 149 150 gid = xact.getGlobalId(); 151 firstLog = xact.getFirstLogInstant(); 152 lastLog = xact.getLastLogInstant(); 153 } 154 } 155 156 159 public TransactionTableEntry() 160 { } 161 162 public void writeExternal(ObjectOutput out) throws IOException 163 { 164 if (SanityManager.DEBUG) 165 { 166 SanityManager.ASSERT(!recovery, "writing out a recovery transaction"); 167 SanityManager.ASSERT(update, "writing out read only transaction"); 168 SanityManager.ASSERT(myxact.getFirstLogInstant() != null, 169 "myxact.getFirstLogInstant is null"); 170 SanityManager.ASSERT(!isClone, "cannot write out a clone"); 171 } 172 173 out.writeObject(xid); 187 out.writeObject(myxact.getGlobalId()); 188 out.writeObject(myxact.getFirstLogInstant()); 189 out.writeObject(myxact.getLastLogInstant()); 190 out.writeInt(transactionStatus); 191 } 192 193 public void readExternal(ObjectInput in) 194 throws ClassNotFoundException , IOException 195 { 196 if (SanityManager.DEBUG) 199 SanityManager.ASSERT(!isClone, "cannot write out a clone"); 200 201 xid = (TransactionId)in.readObject(); 202 gid = (GlobalTransactionId)in.readObject(); 203 firstLog = (LogInstant)in.readObject(); 204 lastLog = (LogInstant)in.readObject(); 205 transactionStatus = in.readInt(); 206 update = true; 207 recovery = true; 208 needExclusion = true; 209 210 if (SanityManager.DEBUG) 211 { 212 SanityManager.ASSERT(xid != null, "read in transaction table entry with null id"); 213 SanityManager.ASSERT(firstLog != null, "read in transaction table entry with firstLog"); 214 } 215 216 } 217 218 219 void setXact(Xact xact) 221 { 222 232 myxact = xact; 233 234 } 235 236 239 public int getTypeFormatId() { 240 return StoredFormatIds.RAW_STORE_TRANSACTION_TABLE_ENTRY; 241 } 242 243 public String toString() 244 { 245 if (SanityManager.DEBUG) 246 { 247 StringBuffer str = new StringBuffer (500). 248 append("Xid=").append(getXid()). 249 append(" gid=").append(getGid()). 250 append(" firstLog=").append(getFirstLog()). 251 append(" lastLog=").append(getLastLog()). 252 append(" transactionStatus=").append(transactionStatus). 253 append(" myxact=").append(myxact). 254 append(" update=").append(update). 255 append(" recovery=").append(recovery). 256 append(" prepare=").append(isPrepared()). 257 append(" needExclusion=").append(needExclusion). 258 append("\n"); 259 return str.toString(); 260 } 261 else 262 return null; 263 } 264 265 void updateTransactionStatus(Xact xact, int status, int attribute) 266 { 267 if (SanityManager.DEBUG) 268 { 269 SanityManager.ASSERT(myxact == xact, 270 "update transaction status for wrong xact"); 271 SanityManager.ASSERT(!isClone, "cannot change a clone"); 272 } 273 274 this.update = (attribute & UPDATE) != 0; 275 } 276 277 void removeUpdateTransaction() 278 { 279 if (SanityManager.DEBUG) 280 SanityManager.ASSERT(!isClone, "cannot change a clone"); 281 282 this.update = false; 283 transactionStatus = 0; 284 285 } 286 287 void unsetRecoveryStatus() 288 { 289 if (SanityManager.DEBUG) 290 SanityManager.ASSERT(!isClone, "cannot change a clone"); 291 292 294 firstLog = null; 295 296 this.recovery = false; 297 } 298 299 void prepareTransaction() 300 { 301 if (SanityManager.DEBUG) 302 SanityManager.ASSERT(!isClone, "cannot change a clone"); 303 304 transactionStatus |= Xact.END_PREPARED; 305 } 306 307 311 312 TransactionId getXid() 313 { 314 if (SanityManager.DEBUG) 315 { 316 SanityManager.ASSERT(xid != null, "TTE with null xid"); 317 SanityManager.ASSERT(!isClone, "cannot call method with a clone"); 318 } 319 320 return xid; 321 } 322 323 public final GlobalTransactionId getGid() 324 { 325 if (SanityManager.DEBUG) 326 SanityManager.ASSERT(!isClone, "cannot call method with a clone"); 327 328 if (gid != null) 329 return gid; 330 331 if (myxact != null) 332 return myxact.getGlobalId(); 333 334 return null; 335 } 336 337 LogInstant getFirstLog() 338 { 339 if (SanityManager.DEBUG) 340 { 341 SanityManager.ASSERT(!isClone, "cannot call method with a clone"); 342 343 if (recovery) 344 { 345 SanityManager.ASSERT( 346 firstLog != null, 347 "a recovery transaction with a null firstLog"); 348 } 349 else 350 { 351 SanityManager.ASSERT( 352 firstLog == null, 353 "a normal transaction with a non-null firstLog" + 354 "myxact.getFirstLogInstant() = " + myxact.getFirstLogInstant()); 355 } 356 } 357 358 if (firstLog != null) 359 return firstLog; 360 361 if (myxact != null) 362 return myxact.getFirstLogInstant(); 363 364 return null; 365 } 366 367 LogInstant getLastLog() 368 { 369 if (SanityManager.DEBUG) 370 SanityManager.ASSERT(!isClone, "cannot call method with a clone"); 371 372 if (lastLog != null) 373 return lastLog; 374 375 if (myxact != null) 376 return myxact.getLastLogInstant(); 377 378 return null; 379 } 380 381 public final Xact getXact() 382 { 383 if (SanityManager.DEBUG) 384 SanityManager.ASSERT(!isClone, "cannot call method with a clone"); 385 386 return myxact; 387 } 388 389 int getTransactionStatus() 390 { 391 if (SanityManager.DEBUG) 392 SanityManager.ASSERT(!isClone, "cannot call method with a clone"); 393 394 return transactionStatus; 395 } 396 397 boolean isUpdate() 398 { 399 if (SanityManager.DEBUG) 400 SanityManager.ASSERT(!isClone, "cannot call method with a clone"); 401 402 return update; 403 } 404 405 boolean isRecovery() 406 { 407 if (SanityManager.DEBUG) 408 SanityManager.ASSERT(!isClone, "cannot call method with a clone"); 409 410 return recovery; 411 } 412 413 boolean isPrepared() 414 { 415 if (SanityManager.DEBUG) 416 SanityManager.ASSERT(!isClone, "cannot call method with a clone"); 417 418 return((transactionStatus & Xact.END_PREPARED) != 0); 419 } 420 421 422 423 424 public boolean needExclusion() 425 { 426 if (SanityManager.DEBUG) 427 SanityManager.ASSERT(!isClone, "cannot call method with a clone"); 428 429 return needExclusion; 430 } 431 432 435 public String getTransactionIdString() 436 { 437 if (SanityManager.DEBUG) 438 { 439 SanityManager.ASSERT( 440 !recovery, "trying to display recovery transaction"); 441 SanityManager.ASSERT(myxact != null, "my xact is null"); 442 SanityManager.ASSERT(isClone, "Should only call method on a clone"); 443 } 444 445 TransactionId t = myxact.getIdNoCheck(); 446 return (t == null) ? "CLOSED" : t.toString(); 447 } 448 449 public String getGlobalTransactionIdString() 450 { 451 if (SanityManager.DEBUG) 452 { 453 SanityManager.ASSERT( 454 !recovery, "trying to display recovery transaction"); 455 SanityManager.ASSERT(myxact != null, "my xact is null"); 456 SanityManager.ASSERT(isClone, "Should only call method on a clone"); 457 } 458 459 GlobalTransactionId gid = myxact.getGlobalId(); 460 return (gid == null) ? null : gid.toString(); 461 } 462 463 public String getUsernameString() 464 { 465 if (SanityManager.DEBUG) 466 SanityManager.ASSERT(isClone, "Should only call method on a clone"); 467 468 getlcc(); 469 return (lcc == null) ? null : lcc.getAuthorizationId(); 470 } 471 472 public String getTransactionTypeString() 473 { 474 if (SanityManager.DEBUG) 475 SanityManager.ASSERT(isClone, "Should only call method on a clone"); 476 477 if (myxact == null) 478 return null; 479 else if (myxact.getTransName() != null) 480 return myxact.getTransName(); 481 else 482 return myxact.getContextId(); 483 } 484 485 public String getTransactionStatusString() 486 { 487 if (SanityManager.DEBUG) 488 SanityManager.ASSERT(isClone, "Should only call method on a clone"); 489 490 return (myxact == null) ? null : myxact.getState(); 491 } 492 493 public String getStatementTextString() 494 { 495 if (SanityManager.DEBUG) 496 SanityManager.ASSERT(isClone, "Should only call method on a clone"); 497 498 getlcc(); 499 if (lcc != null) 500 { 501 StatementContext sc = lcc.getStatementContext(); 502 if (sc != null) 503 return sc.getStatementText() ; 504 } 505 return null; 506 507 } 508 509 public String getFirstLogInstantString() 510 { 511 if (SanityManager.DEBUG) 512 SanityManager.ASSERT(isClone, "Should only call method on a clone"); 513 514 LogInstant logInstant = 515 (myxact == null) ? null : myxact.getFirstLogInstant(); 516 517 return (logInstant == null) ? null : logInstant.toString(); 518 519 } 520 521 private void getlcc() 522 { 523 if (SanityManager.DEBUG) 524 SanityManager.ASSERT(isClone, "Should only call method on a clone"); 525 526 if (lcc == null && myxact != null && myxact.xc != null) 527 { 528 XactContext xc = myxact.xc; 529 530 lcc = (LanguageConnectionContext) 531 xc.getContextManager().getContext( 532 LanguageConnectionContext.CONTEXT_ID); 533 } 534 } 535 536 539 protected Object clone() 540 { 541 try 542 { 543 Object c = super.clone(); 544 ((TransactionTableEntry)c).isClone = true; 545 546 return c; 547 } 548 catch (CloneNotSupportedException e) 549 { 550 if (SanityManager.DEBUG) 552 { 553 SanityManager.THROWASSERT( 554 "TransactionTableEntry cloneable but throws CloneNotSupportedException " + e); 555 } 556 return null; 557 } 558 } 559 } 560 | Popular Tags |