1 24 25 package org.continuent.sequoia.controller.virtualdatabase.protocol; 26 27 import java.io.Serializable ; 28 import java.sql.SQLException ; 29 import java.util.LinkedList ; 30 31 import org.continuent.sequoia.common.exceptions.NoMoreBackendException; 32 import org.continuent.sequoia.common.i18n.Translate; 33 import org.continuent.sequoia.common.log.Trace; 34 import org.continuent.sequoia.controller.loadbalancer.AllBackendsFailedException; 35 import org.continuent.sequoia.controller.requestmanager.TransactionMetaData; 36 import org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager; 37 import org.continuent.sequoia.controller.requests.AbstractRequest; 38 import org.continuent.sequoia.controller.requests.UnknownWriteRequest; 39 40 46 public class DistributedRollback extends DistributedTransactionMarker 47 { 48 private static final long serialVersionUID = -8954391235872189513L; 49 50 private String login; 54 55 61 public DistributedRollback(String login, long transactionId) 62 { 63 super(transactionId); 64 this.login = login; 65 } 66 67 70 public Object scheduleCommand(DistributedRequestManager drm) 71 throws SQLException  72 { 73 LinkedList totalOrderQueue = drm.getVirtualDatabase().getTotalOrderQueue(); 74 if (totalOrderQueue != null) 75 { 76 synchronized (totalOrderQueue) 77 { 78 totalOrderQueue.addLast(this); 79 } 80 } 81 return this; 82 } 83 84 93 public Serializable executeCommand(DistributedRequestManager drm) 94 throws SQLException  95 { 96 boolean hasBeenScheduled = false; 97 boolean transactionStartedOnThisController = true; 98 Long tid = new Long (transactionId); 99 TransactionMetaData tm; 100 try 101 { 102 tm = drm.getTransactionMetaData(tid); 103 } 104 catch (SQLException ignore) 105 { 106 transactionStartedOnThisController = false; 109 tm = new TransactionMetaData(transactionId, 0, login, false, 0); 110 } 111 112 Trace logger = drm.getLogger(); 113 try 114 { 115 if (transactionStartedOnThisController) 116 { 117 drm.getScheduler().rollback(tm, this); 118 hasBeenScheduled = true; 119 } 120 121 if (logger.isDebugEnabled()) 122 logger 123 .debug(Translate.get("transaction.rollback", String.valueOf(tid))); 124 125 drm.getLoadBalancer().rollback(tm); 127 128 drm.getRecoveryLog().logRequestCompletion(tm.getLogId(), true, 0); 130 131 if ((drm.getResultCache() != null) 134 && (tm.altersQueryResultCache() || tm.altersDatabaseSchema())) 135 drm.getResultCache().rollback(tm.getTransactionId()); 136 137 if (tm.altersDatabaseSchema()) 139 { 140 if (drm.getMetadataCache() != null) 141 drm.getMetadataCache().flushCache(); 142 drm.setSchemaIsDirty(true); 143 } 144 145 if (hasBeenScheduled) 147 drm.getScheduler().rollbackCompleted(tm, true); 148 149 if (transactionStartedOnThisController) 150 { 151 drm.completeTransaction(tid); 152 } 153 } 154 catch (NoMoreBackendException e) 155 { 156 if (logger.isDebugEnabled()) 157 logger 158 .debug(Translate.get( 159 "virtualdatabase.distributed.rollback.logging.only", 160 transactionId)); 161 addRollbackFailureOnAllBackends(drm, hasBeenScheduled, tm); 162 throw e; 163 } 164 catch (SQLException e) 165 { 166 if (tm.isReadOnly()) 167 { 168 if (logger.isWarnEnabled()) 169 { 170 logger 171 .warn("Ignoring failure of rollback for read-only transaction, exception was: " 172 + e); 173 } 174 175 if (hasBeenScheduled) 176 drm.getScheduler().rollbackCompleted(tm, true); 177 178 return Boolean.TRUE; 179 } 180 181 addRollbackFailureOnAllBackends(drm, hasBeenScheduled, tm); 182 logger.warn(Translate 183 .get("virtualdatabase.distributed.rollback.sqlexception"), e); 184 return e; 185 } 186 catch (RuntimeException re) 187 { 188 addRollbackFailureOnAllBackends(drm, hasBeenScheduled, tm); 189 logger.warn(Translate 190 .get("virtualdatabase.distributed.rollback.exception"), re); 191 throw new SQLException (re.getMessage()); 192 } 193 catch (AllBackendsFailedException e) 194 { 195 addRollbackFailureOnAllBackends(drm, hasBeenScheduled, tm); 196 if (logger.isDebugEnabled()) 197 logger.debug(Translate.get( 198 "virtualdatabase.distributed.commit.all.backends.locally.failed", 199 transactionId)); 200 return e; 201 } 202 return Boolean.TRUE; 203 } 204 205 private void addRollbackFailureOnAllBackends(DistributedRequestManager drm, 206 boolean hasBeenScheduled, TransactionMetaData tm) 207 { 208 AbstractRequest request = new UnknownWriteRequest("rollback", false, 0, 209 "\n"); 210 request.setTransactionId(transactionId); 211 request.setLogId(tm.getLogId()); 212 drm.addFailedOnAllBackends(request, hasBeenScheduled); 213 } 214 215 218 public String toString() 219 { 220 return "Rollback transaction " + transactionId; 221 } 222 } | Popular Tags |