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 DistributedCommit extends DistributedTransactionMarker 47 { 48 private static final long serialVersionUID = 1222810057093662283L; 49 50 private String login; 54 55 61 public DistributedCommit(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 transactionStartedOnThisController = true; 97 Long tid = new Long (transactionId); 98 TransactionMetaData tm; 99 try 100 { 101 tm = drm.getTransactionMetaData(tid); 102 } 103 catch (SQLException ignore) 104 { 105 transactionStartedOnThisController = false; 108 tm = new TransactionMetaData(transactionId, 0, login, false, 0); 109 } 110 111 Trace logger = drm.getLogger(); 112 boolean hasBeenScheduled = false; 113 try 114 { 115 if (transactionStartedOnThisController) 116 { 117 drm.getScheduler().commit(tm, false, this); 118 hasBeenScheduled = true; 119 } 120 121 if (logger.isDebugEnabled()) 122 logger.debug(Translate.get("transaction.commit", String.valueOf(tid))); 123 124 drm.getLoadBalancer().commit(tm); 126 127 if (drm.getResultCache() != null) 129 drm.getResultCache().commit(tm.getTransactionId()); 130 131 drm.getRecoveryLog().logRequestCompletion(tm.getLogId(), true, 0); 133 134 if (transactionStartedOnThisController) 135 { 136 drm.getScheduler().commitCompleted(tm, true); 138 drm.completeTransaction(tid); 139 } 140 } 141 catch (NoMoreBackendException e) 142 { 143 addFailedCommitOnAllBackends(drm, tm, hasBeenScheduled); 144 throw e; 145 } 146 catch (SQLException e) 147 { 148 149 if (tm.isReadOnly()) 150 { 151 boolean beginLogged = false; 152 if (drm.getRecoveryLog() != null) 153 { 154 beginLogged = drm.getRecoveryLog().hasLoggedBeginForTransaction(tid); 155 } 156 if (!beginLogged) 157 { 158 if (logger.isWarnEnabled()) 159 160 { 161 logger 162 .warn("Ignoring failure of commit for read-only transaction, exception was: " 163 + e); 164 } 165 166 if (hasBeenScheduled) 167 drm.getScheduler().commitCompleted(tm, true); 168 169 if (transactionStartedOnThisController) 170 { 171 drm.completeTransaction(tid); 172 } 173 return Boolean.TRUE; 174 } 175 } 176 addFailedCommitOnAllBackends(drm, tm, hasBeenScheduled); 177 logger.warn(Translate 178 .get("virtualdatabase.distributed.commit.sqlexception"), e); 179 return e; 180 } 181 catch (RuntimeException re) 182 { 183 addFailedCommitOnAllBackends(drm, tm, hasBeenScheduled); 184 logger.warn( 185 Translate.get("virtualdatabase.distributed.commit.exception"), re); 186 throw new SQLException (re.getMessage()); 187 } 188 catch (AllBackendsFailedException e) 189 { 190 addFailedCommitOnAllBackends(drm, tm, hasBeenScheduled); 191 if (logger.isDebugEnabled()) 192 logger.debug(Translate.get( 193 "virtualdatabase.distributed.commit.all.backends.locally.failed", 194 transactionId)); 195 return e; 196 } 197 198 return Boolean.TRUE; 199 } 200 201 private void addFailedCommitOnAllBackends(DistributedRequestManager drm, 202 TransactionMetaData tm, boolean hasBeenScheduled) 203 { 204 AbstractRequest request = new UnknownWriteRequest("commit", false, 0, "\n"); 205 request.setTransactionId(transactionId); 206 request.setLogId(tm.getLogId()); 207 drm.addFailedOnAllBackends(request, hasBeenScheduled); 208 } 209 210 213 public String toString() 214 { 215 return "Commit transaction " + transactionId; 216 } 217 } | Popular Tags |