1 23 24 package org.continuent.sequoia.controller.loadbalancer.tasks; 25 26 import java.sql.Connection ; 27 import java.sql.SQLException ; 28 import java.sql.Savepoint ; 29 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.connection.PooledConnection; 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.UnknownWriteRequest; 39 40 47 public class RollbackToSavepointTask extends AbstractTask 48 { 49 50 private TransactionMetaData tm; 51 52 private String savepointName; 53 54 static Trace endUserLogger = Trace 55 .getLogger("org.continuent.sequoia.enduser"); 56 57 66 public RollbackToSavepointTask(int nbToComplete, int totalNb, 67 TransactionMetaData tm, String savepointName) throws NullPointerException 68 { 69 super(nbToComplete, totalNb, tm.isPersistentConnection(), tm 70 .getPersistentConnectionId()); 71 if (tm == null) 72 throw new NullPointerException ("Unexpected null metadata in BeginTask"); 73 this.tm = tm; 74 this.savepointName = savepointName; 75 } 76 77 80 public void executeTask(BackendWorkerThread backendThread) 81 throws SQLException 82 { 83 DatabaseBackend backend = backendThread.getBackend(); 84 Long lTid = new Long (tm.getTransactionId()); 85 86 AbstractConnectionManager cm = backend.getConnectionManager(tm.getLogin()); 87 if (cm == null) 88 { 89 SQLException se = new SQLException ( 90 "No Connection Manager for Virtual Login:" + tm.getLogin()); 91 try 92 { 93 notifyFailure(backendThread, -1, se); 94 } 95 catch (SQLException ignore) 96 { 97 98 } 99 throw se; 100 } 101 102 PooledConnection pc = cm.retrieveConnectionForTransaction(tm 103 .getTransactionId()); 104 105 if (pc == null) 107 { backend.stopTransaction(lTid); 109 SQLException se = new SQLException ( 110 "Unable to retrieve connection for transaction " 111 + tm.getTransactionId()); 112 try 113 { if (!notifyFailure(backendThread, tm.getTimeout(), se)) 115 return; 116 } 117 catch (SQLException ignore) 118 { 119 } 120 backendThread.getLoadBalancer().disableBackend(backend, true); 123 String msg = "Failed to rollback transaction " + tm.getTransactionId() 124 + " to savepoint " + savepointName + " on backend " 125 + backend.getName() + " but " + getSuccess() + " succeeded (" + se 126 + ")"; 127 backendThread.getLogger().error(msg); 128 endUserLogger.error(Translate.get("loadbalancer.backend.disabling", 129 backend.getName())); 130 throw new SQLException (msg); 131 } 132 133 try 135 { 136 Savepoint savepoint = backend.getSavepoint(lTid, savepointName); 137 if (savepoint != null) 138 { 139 Connection c = pc.getConnection(); 140 c.rollback(savepoint); 141 } 142 else 143 { 144 String msg = "No savepoint named " + savepointName 145 + " was found cannot rollback to savepoint in transaction " + lTid; 146 backend.getLogger().warn(msg); 147 throw new SQLException (msg); 148 } 149 150 if (tm.altersDatabaseSchema()) 151 { UnknownWriteRequest fakeRequest = new UnknownWriteRequest("rollback " 153 + savepointName, false, 0, null); 154 fakeRequest.setLogin(tm.getLogin()); 155 fakeRequest.setIsAutoCommit(false); 156 fakeRequest.setTransactionId(getTransactionId()); 157 fakeRequest.setPersistentConnection(isPersistentConnection()); 158 fakeRequest.setPersistentConnectionId(getPersistentConnectionId()); 159 backendThread.getBackend().setSchemaIsDirty(true, fakeRequest); 160 } 161 } 162 catch (Exception e) 163 { 164 try 165 { 166 if (!notifyFailure(backendThread, tm.getTimeout(), new SQLException (e 167 .getMessage()).initCause(e))) 168 return; 169 } 170 catch (SQLException ignore) 171 { 172 } 173 backendThread.getLoadBalancer().disableBackend(backend, true); 176 String msg = "Failed to rollback transaction " + tm.getTransactionId() 177 + " to savepoint " + savepointName + " on backend " 178 + backend.getName() + " but " + getSuccess() + " succeeded (" + e 179 + ")"; 180 backendThread.getLogger().error(msg); 181 endUserLogger.error(Translate.get("loadbalancer.backend.disabling", 182 backend.getName())); 183 throw new SQLException (msg); 184 } 185 notifySuccess(backendThread); 186 } 187 188 191 public AbstractRequest getRequest() 192 { 193 return null; 194 } 195 196 199 public String getSavepointName() 200 { 201 return savepointName; 202 } 203 204 207 public long getTransactionId() 208 { 209 return tm.getTransactionId(); 210 } 211 212 215 public boolean isAutoCommit() 216 { 217 return false; 218 } 219 220 223 public boolean equals(Object other) 224 { 225 if ((other == null) || !(other instanceof RollbackToSavepointTask)) 226 return false; 227 228 RollbackToSavepointTask rollbackSavepoint = (RollbackToSavepointTask) other; 229 return (this.getTransactionId() == rollbackSavepoint.getTransactionId()) 230 && (this.savepointName.equals(rollbackSavepoint.getSavepointName())); 231 } 232 233 236 public int hashCode() 237 { 238 return (int) this.getTransactionId(); 239 } 240 241 244 public String toString() 245 { 246 return "RollbackToSavepointTask for transaction " + tm.getTransactionId() 247 + " (" + savepointName + ")"; 248 } 249 } 250 | Popular Tags |