1 22 23 package org.continuent.sequoia.controller.loadbalancer.tasks; 24 25 import java.sql.Connection ; 26 import java.sql.SQLException ; 27 28 import org.continuent.sequoia.common.exceptions.NoTransactionStartWhenDisablingException; 29 import org.continuent.sequoia.common.exceptions.UnreachableBackendException; 30 import org.continuent.sequoia.common.i18n.Translate; 31 import org.continuent.sequoia.common.log.Trace; 32 import org.continuent.sequoia.controller.backend.DatabaseBackend; 33 import org.continuent.sequoia.controller.connection.AbstractConnectionManager; 34 import org.continuent.sequoia.controller.loadbalancer.AbstractLoadBalancer; 35 import org.continuent.sequoia.controller.loadbalancer.BackendWorkerThread; 36 import org.continuent.sequoia.controller.requestmanager.TransactionMetaData; 37 import org.continuent.sequoia.controller.requests.AbstractRequest; 38 import org.continuent.sequoia.controller.requests.UnknownReadRequest; 39 40 52 public class BeginTask extends AbstractTask 53 { 54 private TransactionMetaData tm; 56 private AbstractRequest request; 57 static Trace endUserLogger = Trace 58 .getLogger("org.continuent.sequoia.enduser"); 59 60 68 public BeginTask(int nbToComplete, int totalNb, TransactionMetaData tm) 69 throws NullPointerException 70 { 71 super(nbToComplete, totalNb, tm.isPersistentConnection(), tm 72 .getPersistentConnectionId()); 73 if (tm == null) 74 throw new NullPointerException ("Unexpected null metadata in BeginTask"); 75 this.tm = tm; 76 this.request = new UnknownReadRequest("begin", false, 0, ""); 77 request.setLogin(tm.getLogin()); 78 request.setIsAutoCommit(false); 79 request.setTransactionId(tm.getTransactionId()); 80 request.setPersistentConnection(tm.isPersistentConnection()); 81 request.setPersistentConnectionId(tm.getPersistentConnectionId()); 82 request 83 .setTransactionIsolation(org.continuent.sequoia.driver.Connection.DEFAULT_TRANSACTION_ISOLATION_LEVEL); 84 } 85 86 92 public void executeTask(BackendWorkerThread backendThread) 93 throws SQLException 94 { 95 DatabaseBackend backend = backendThread.getBackend(); 96 if (!backend.isReplaying()) 97 throw new SQLException ( 98 "BeginTask should only be used for recovery purposes. Detected incorrect backend state:" 99 + backend.getState()); 100 101 try 102 { 103 AbstractConnectionManager cm = backend 104 .getConnectionManager(tm.getLogin()); 105 if (cm == null) 106 { 107 SQLException se = new SQLException ( 108 "No Connection Manager for Virtual Login:" + tm.getLogin()); 109 try 110 { 111 notifyFailure(backendThread, 1, se); 112 } 113 catch (SQLException ignore) 114 { 115 116 } 117 throw se; 118 } 119 120 Connection c; 121 Long lTid = new Long (tm.getTransactionId()); 122 Trace logger = backendThread.getLogger(); 123 124 try 125 { 126 c = AbstractLoadBalancer.getConnectionAndBeginTransaction(backend, cm, 127 request); 128 backend.startTransaction(lTid); 129 } 130 catch (UnreachableBackendException ube) 131 { 132 SQLException se = new SQLException ("Backend " + backend.getName() 133 + " is no more reachable."); 134 try 135 { 136 notifyFailure(backendThread, -1, se); 137 } 138 catch (SQLException ignore) 139 { 140 } 141 backendThread.getLoadBalancer().disableBackend(backend, true); 144 String msg = Translate.get( 145 "loadbalancer.backend.disabling.unreachable", backend.getName()); 146 logger.error(msg); 147 endUserLogger.error(msg); 148 throw se; 149 } 150 catch (NoTransactionStartWhenDisablingException e) 151 { 152 notifyCompletion(backendThread); 156 return; 157 } 158 catch (SQLException e1) 159 { 160 SQLException se = new SQLException ( 161 "Unable to get connection for transaction " + lTid); 162 try 163 { if (!notifyFailure(backendThread, tm.getTimeout(), se)) 165 return; 166 } 167 catch (SQLException ignore) 168 { 169 } 170 backendThread.getLoadBalancer().disableBackend(backend, true); 173 String msg = "Begin of transaction " + tm.getTransactionId() 174 + " failed on backend " + backend.getName() + " but " 175 + getSuccess() + " succeeded (" + se + ")"; 176 logger.error(msg); 177 endUserLogger.error(Translate.get( 178 "loadbalancer.backend.disabling", backend.getName())); 179 throw new SQLException (msg); 180 } 181 182 if (c == null) 184 { SQLException se = new SQLException ( 186 "No more connection to start a new transaction."); 187 try 188 { if (!notifyFailure(backendThread, tm.getTimeout(), se)) 190 return; 191 } 192 catch (SQLException ignore) 193 { 194 } 195 } 196 else 197 { 198 notifySuccess(backendThread); 199 } 200 } 201 catch (Exception e) 202 { 203 try 204 { 205 if (!notifyFailure(backendThread, tm.getTimeout(), new SQLException (e 206 .getMessage()))) 207 return; 208 } 209 catch (SQLException ignore) 210 { 211 } 212 String msg = "Failed to begin transaction " + tm.getTransactionId() 213 + " on backend " + backend.getName() + " (" + e + ")"; 214 backendThread.getLogger().error(msg); 215 throw new SQLException (msg); 216 } 217 } 218 219 222 public AbstractRequest getRequest() 223 { 224 return request; 225 } 226 227 230 public long getTransactionId() 231 { 232 return tm.getTransactionId(); 233 } 234 235 238 public boolean isAutoCommit() 239 { 240 return false; 241 } 242 243 246 public boolean equals(Object other) 247 { 248 if ((other == null) || !(other instanceof BeginTask)) 249 return false; 250 251 BeginTask begin = (BeginTask) other; 252 return this.getTransactionId() == begin.getTransactionId(); 253 } 254 255 258 public int hashCode() 259 { 260 return (int) this.getTransactionId(); 261 } 262 263 266 public String toString() 267 { 268 return "BeginTask (" + tm.getLogin() + "," + tm.getTransactionId() + ")"; 269 } 270 271 } | Popular Tags |