001: /**
002: * Sequoia: Database clustering technology.
003: * Copyright (C) 2002-2004 French National Institute For Research In Computer
004: * Science And Control (INRIA).
005: * Copyright (C) 2005 AmicoSoft, Inc. dba Emic Networks
006: * Copyright (C) 2005-2006 Continuent, Inc.
007: * Contact: sequoia@continuent.org
008: *
009: * Licensed under the Apache License, Version 2.0 (the "License");
010: * you may not use this file except in compliance with the License.
011: * You may obtain a copy of the License at
012: *
013: * http://www.apache.org/licenses/LICENSE-2.0
014: *
015: * Unless required by applicable law or agreed to in writing, software
016: * distributed under the License is distributed on an "AS IS" BASIS,
017: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018: * See the License for the specific language governing permissions and
019: * limitations under the License.
020: *
021: * Initial developer(s): Emmanuel Cecchet.
022: * Contributor(s): ______________________.
023: */package org.continuent.sequoia.controller.virtualdatabase.protocol;
024:
025: import java.io.Serializable;
026: import java.sql.SQLException;
027: import java.util.LinkedList;
028:
029: import org.continuent.sequoia.common.exceptions.NoMoreBackendException;
030: import org.continuent.sequoia.common.i18n.Translate;
031: import org.continuent.sequoia.controller.backend.result.ExecuteUpdateResult;
032: import org.continuent.sequoia.controller.loadbalancer.AllBackendsFailedException;
033: import org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager;
034: import org.continuent.sequoia.controller.requests.AbstractWriteRequest;
035:
036: /**
037: * Execute a distributed call to Statement.executeUpdate() between several
038: * controllers.
039: *
040: * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
041: * @version 1.0
042: */
043: public class DistributedStatementExecuteUpdate extends
044: DistributedRequest {
045: private static final long serialVersionUID = -4849018153223926739L;
046:
047: /**
048: * @param request write request to execute
049: */
050: public DistributedStatementExecuteUpdate(
051: AbstractWriteRequest request) {
052: super (request);
053: }
054:
055: /**
056: * @see org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedRequest#scheduleRequest(org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager)
057: */
058: public Object scheduleRequest(DistributedRequestManager drm)
059: throws SQLException {
060: LinkedList totalOrderQueue = drm.getVirtualDatabase()
061: .getTotalOrderQueue();
062: synchronized (totalOrderQueue) {
063: totalOrderQueue.addLast(request);
064: }
065: return request;
066: }
067:
068: /**
069: * @see org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedRequest#executeScheduledRequest(org.continuent.sequoia.controller.requestmanager.distributed.DistributedRequestManager)
070: */
071: public Serializable executeScheduledRequest(
072: DistributedRequestManager drm) throws SQLException {
073: boolean hasBeenScheduled = false;
074:
075: try {
076: drm.getLoadBalancer().waitForSuspendWritesToComplete(
077: request);
078:
079: // This call will trigger a lazyTransactionStart as well
080: drm
081: .scheduleExecWriteRequest((AbstractWriteRequest) request);
082: hasBeenScheduled = true;
083:
084: ExecuteUpdateResult execWriteRequestResult = drm
085: .loadBalanceStatementExecuteUpdate((AbstractWriteRequest) request);
086: drm.updateAndNotifyExecWriteRequest(
087: (AbstractWriteRequest) request,
088: execWriteRequestResult.getUpdateCount());
089: return execWriteRequestResult;
090: } catch (NoMoreBackendException e) {
091: if (drm.getLogger().isDebugEnabled())
092: drm
093: .getLogger()
094: .debug(
095: Translate
096: .get(
097: "virtualdatabase.distributed.write.logging.only",
098: request
099: .getSqlShortForm(drm
100: .getVirtualDatabase()
101: .getSqlShortFormLength())));
102:
103: drm.addFailedOnAllBackends(request, hasBeenScheduled);
104: return e;
105: } catch (AllBackendsFailedException e) {
106: // Add to failed list, the scheduler has already been notified by either
107: // loadBalanceExecWriteRequest or updateAndNotifyExecWriteRequest.
108: drm.addFailedOnAllBackends(request, hasBeenScheduled);
109: if (drm.getLogger().isDebugEnabled())
110: drm
111: .getLogger()
112: .debug(
113: Translate
114: .get(
115: "virtualdatabase.distributed.write.all.backends.locally.failed",
116: request
117: .getSqlShortForm(drm
118: .getVirtualDatabase()
119: .getSqlShortFormLength())));
120: return e;
121: } catch (SQLException e) {
122: // Something bad more likely happened during the update but the scheduler
123: // has already been notified.
124: drm.addFailedOnAllBackends(request, hasBeenScheduled);
125: drm
126: .getLogger()
127: .warn(
128: Translate
129: .get(
130: "virtualdatabase.distributed.write.sqlexception",
131: e.getMessage()), e);
132: return e;
133: } catch (RuntimeException re) {
134: // Something bad more likely happened during the update but the scheduler
135: // has already been notified.
136: drm.addFailedOnAllBackends(request, hasBeenScheduled);
137: drm
138: .getLogger()
139: .warn(
140: Translate
141: .get(
142: "virtualdatabase.distributed.write.exception",
143: re.getMessage()), re);
144: return new SQLException(re.getMessage());
145: }
146: }
147:
148: /**
149: * @see java.lang.Object#toString()
150: */
151: public String toString() {
152: return "W " + request.getId() + " "
153: + request.getTransactionId() + " "
154: + request.getUniqueKey();
155: }
156:
157: }
|