1 23 24 package org.continuent.sequoia.controller.virtualdatabase.protocol; 25 26 import java.io.Serializable ; 27 import java.sql.SQLException ; 28 import java.util.LinkedList ; 29 30 import org.continuent.sequoia.common.exceptions.NoMoreBackendException; 31 import org.continuent.sequoia.common.i18n.Translate; 32 import org.continuent.sequoia.common.log.Trace; 33 import org.continuent.sequoia.controller.requestmanager.TransactionMetaData; 34 import org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager; 35 import org.continuent.sequoia.controller.requests.AbstractRequest; 36 import org.continuent.sequoia.controller.requests.UnknownWriteRequest; 37 import org.continuent.sequoia.controller.virtualdatabase.VirtualDatabaseWorkerThread; 38 39 46 public class DistributedAbort extends DistributedTransactionMarker 47 { 48 private static final long serialVersionUID = -8954391235872189513L; 49 50 private transient Long tid; 51 private String login; 55 56 private DistributedRollback totalOrderAbort; 57 58 64 public DistributedAbort(String login, long transactionId) 65 { 66 super(transactionId); 67 this.login = login; 68 } 69 70 73 public Object scheduleCommand(DistributedRequestManager drm) 74 throws SQLException 75 { 76 LinkedList totalOrderQueue = drm.getVirtualDatabase().getTotalOrderQueue(); 77 if (totalOrderQueue != null) 78 { 79 synchronized (totalOrderQueue) 80 { 81 totalOrderAbort = new DistributedRollback(login, transactionId); 82 totalOrderQueue.addLast(totalOrderAbort); 83 } 84 } 85 return totalOrderAbort; 86 } 87 88 97 public Serializable executeCommand(DistributedRequestManager drm) 98 throws SQLException 99 { 100 Trace logger = drm.getLogger(); 101 102 boolean transactionStartedOnThisController = true; 103 tid = new Long (transactionId); 104 TransactionMetaData tm; 105 try 106 { 107 tm = drm.getTransactionMetaData(tid); 108 } 109 catch (SQLException ignore) 110 { 111 transactionStartedOnThisController = false; 114 tm = new TransactionMetaData(transactionId, 0, login, false, 0); 115 } 116 117 VirtualDatabaseWorkerThread vdbwt = drm.getVirtualDatabase() 118 .getVirtualDatabaseWorkerThreadForTransaction(transactionId); 119 if (vdbwt != null) 120 vdbwt.notifyAbort(transactionId); 121 122 boolean hasBeenScheduled = false; 123 try 124 { 125 if (transactionStartedOnThisController) 126 { drm.getScheduler().rollback(tm, totalOrderAbort); 128 hasBeenScheduled = true; 129 } 130 131 if (logger.isDebugEnabled()) 132 logger.debug(Translate.get("transaction.aborting", tid)); 133 134 drm.getLoadBalancer().abort(tm); 136 137 drm.getRecoveryLog().logRequestCompletion(tm.getLogId(), true, 0); 139 140 if ((drm.getResultCache() != null) 143 && (tm.altersQueryResultCache() || tm.altersDatabaseSchema())) 144 drm.getResultCache().rollback(transactionId); 145 146 if (tm.altersDatabaseSchema()) 148 { 149 if (drm.getMetadataCache() != null) 150 drm.getMetadataCache().flushCache(); 151 drm.setSchemaIsDirty(true); 152 } 153 154 if (hasBeenScheduled) { 156 drm.getScheduler().rollbackCompleted(tm, true); 158 } 159 } 160 catch (NoMoreBackendException e) 161 { 162 if (logger.isDebugEnabled()) 163 logger.debug(Translate.get( 164 "virtualdatabase.distributed.abort.logging.only", transactionId)); 165 166 addAbortFailureOnAllBackends(drm, hasBeenScheduled, tm); 167 throw e; 168 } 169 catch (SQLException e) 170 { 171 logger.warn(Translate 172 .get("virtualdatabase.distributed.abort.sqlexception"), e); 173 addAbortFailureOnAllBackends(drm, hasBeenScheduled, tm); 174 return e; 175 } 176 catch (RuntimeException re) 177 { 178 logger.warn(Translate 179 .get("virtualdatabase.distributed.rollback.exception"), re); 180 addAbortFailureOnAllBackends(drm, hasBeenScheduled, tm); 181 throw new SQLException (re.getMessage()); 182 } 183 finally 184 { 185 if (!hasBeenScheduled) 186 { 187 if (drm.getLoadBalancer().waitForTotalOrder(totalOrderAbort, false)) 190 drm.getLoadBalancer().removeObjectFromAndNotifyTotalOrderQueue( 191 totalOrderAbort); 192 } 193 194 if (transactionStartedOnThisController) 195 { 196 drm.completeTransaction(tid); 197 } 198 199 if (logger.isDebugEnabled()) 200 logger.debug(Translate.get("transaction.aborted", tid)); 201 } 202 return Boolean.TRUE; 203 } 204 205 private void addAbortFailureOnAllBackends(DistributedRequestManager drm, 206 boolean hasBeenScheduled, TransactionMetaData tm) 207 { 208 AbstractRequest abortRequest = new UnknownWriteRequest("abort", false, 0, 209 "\n"); 210 abortRequest.setLogin(login); 211 abortRequest.setTransactionId(transactionId); 212 abortRequest.setIsAutoCommit(false); 213 abortRequest.setLogId(tm.getLogId()); 214 drm.addFailedOnAllBackends(abortRequest, hasBeenScheduled); 215 } 216 217 220 public String toString() 221 { 222 return "Abort transaction " + transactionId; 223 } 224 } | Popular Tags |