1 5 package com.tc.object.tx; 6 7 import com.tc.net.protocol.tcm.ChannelIDProvider; 8 import com.tc.object.ObjectID; 9 import com.tc.object.TCObject; 10 import com.tc.object.lockmanager.api.LockID; 11 import com.tc.util.SequenceID; 12 13 16 abstract class AbstractClientTransaction implements ClientTransaction { 17 18 private SequenceID seqID = SequenceID.NULL_ID; 19 private final TransactionID txID; 20 private TransactionContext transactionContext; 21 private boolean alreadyCommittedFlag; 22 private final ChannelIDProvider cidProvider; 23 24 AbstractClientTransaction(TransactionID txID, ChannelIDProvider cidProvider) { 25 this.txID = txID; 26 this.cidProvider = cidProvider; 27 } 28 29 public synchronized void setSequenceID(SequenceID sequenceID) { 30 if (!seqID.isNull()) throw new AssertionError ("Attempt to set sequence id more than once."); 31 if (sequenceID == null || sequenceID.isNull()) throw new AssertionError ("Attempt to set sequence id to null: " 32 + sequenceID); 33 this.seqID = sequenceID; 34 } 35 36 public synchronized SequenceID getSequenceID() { 37 return this.seqID; 38 } 39 40 public void setTransactionContext(TransactionContext transactionContext) { 41 this.transactionContext = transactionContext; 42 } 43 44 public TxnType getTransactionType() { 45 return transactionContext.getType(); 46 } 47 48 public LockID[] getAllLockIDs() { 49 return transactionContext.getAllLockIDs(); 50 } 51 52 public TransactionID getTransactionID() { 53 return txID; 54 } 55 56 public LockID getLockID() { 57 return transactionContext.getLockID(); 58 } 59 60 public final void createObject(TCObject source) { 61 if (transactionContext.getType() == TxnType.READ_ONLY) { throw new AssertionError ( 62 source.getClass().getName() 63 + " was already checked to have write access!"); } 64 alreadyCommittedCheck(); 65 basicCreate(source); 66 } 67 68 public final void createRoot(String name, ObjectID rootID) { 69 if (transactionContext.getType() == TxnType.READ_ONLY) { throw new AssertionError ( 70 name 71 + " was already checked to have write access!"); } 72 alreadyCommittedCheck(); 73 basicCreateRoot(name, rootID); 74 } 75 76 public final void fieldChanged(TCObject source, String classname, String fieldname, Object newValue, int index) { 77 if (transactionContext.getType() == TxnType.READ_ONLY) { 78 throwReadOnlyException("Failed To Modify Field: " + fieldname + " in " + classname); 79 } 80 81 if (source.getTCClass().isEnum()) { throw new AssertionError ("fieldChanged() on an enum type " 82 + source.getTCClass().getPeerClass().getName()); } 83 84 alreadyCommittedCheck(); 85 basicFieldChanged(source, classname, fieldname, newValue, index); 86 } 87 88 public final void literalValueChanged(TCObject source, Object newValue, Object oldValue) { 89 if (transactionContext.getType() == TxnType.READ_ONLY) { 90 throwReadOnlyException("Failed To Change Value in: " + newValue.getClass().getName()); 91 } 92 alreadyCommittedCheck(); 93 basicLiteralValueChanged(source, newValue, oldValue); 94 } 95 96 public final void arrayChanged(TCObject source, int startPos, Object array, int length) { 97 if (transactionContext.getType() == TxnType.READ_ONLY) { 98 throwReadOnlyException("Failed To Modify Array: " + array.getClass().getName()); 99 } 100 alreadyCommittedCheck(); 101 basicArrayChanged(source, startPos, array, length); 102 } 103 104 public final void logicalInvoke(TCObject source, int method, Object [] parameters, String methodName) { 105 if (transactionContext.getType() == TxnType.READ_ONLY) { 106 throwReadOnlyException("Failed Method Call: " + methodName); 107 } 108 alreadyCommittedCheck(); 109 basicLogicalInvoke(source, method, parameters); 110 } 111 112 public boolean isNull() { 113 return false; 114 } 115 116 protected void alreadyCommittedCheck() { 117 if (alreadyCommittedFlag) { throw new AssertionError ("Transaction " + txID + " already commited."); } 118 } 119 120 private void throwReadOnlyException(String details) { 121 long vmId = ReadOnlyException.INVALID_VMID; 122 if (cidProvider != null) { 123 vmId = cidProvider.getChannelID().toLong(); 124 } 125 ReadOnlyException roe = new ReadOnlyException( 126 "Current transaction with read-only access attempted to modify a shared object. " 127 + "\nPlease alter the locks section of your Terracotta configuration so that the methods involved in this transaction have read/write access.", 128 Thread.currentThread().getName(), vmId, details); 129 System.err.println(roe.getMessage()); 130 throw roe; 131 } 132 133 public void setAlreadyCommitted() { 134 alreadyCommittedCheck(); 135 this.alreadyCommittedFlag = true; 136 } 137 138 abstract protected void basicCreate(TCObject object); 139 140 abstract protected void basicCreateRoot(String name, ObjectID rootID); 141 142 abstract protected void basicFieldChanged(TCObject source, String classname, String fieldname, Object newValue, 143 int index); 144 145 abstract protected void basicLiteralValueChanged(TCObject source, Object newValue, Object oldValue); 146 147 abstract protected void basicArrayChanged(TCObject source, int startPos, Object array, int length); 148 149 abstract protected void basicLogicalInvoke(TCObject source, int method, Object [] parameters); 150 151 } 152 | Popular Tags |