001: /*
002:
003: Derby - Class org.apache.derby.client.net.NetXAConnection
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.client.net;
023:
024: import java.sql.SQLException;
025:
026: import javax.transaction.xa.XAException;
027: import javax.transaction.xa.XAResource;
028: import javax.transaction.xa.Xid;
029:
030: import org.apache.derby.client.am.SqlException;
031: import org.apache.derby.client.am.Statement;
032:
033: import org.apache.derby.client.ClientPooledConnection;
034: import org.apache.derby.client.am.ClientMessageId;
035: import org.apache.derby.shared.common.reference.SQLState;
036:
037: import org.apache.derby.jdbc.ClientDriver;
038:
039: public class NetXAConnection {
040: private NetConnection netCon;
041:
042: //---------------------constructors/finalizer---------------------------------
043: // For XA Connections
044: /**
045: *
046: * The construcor for the NetXAConnection. The parameter
047: * is set to <code>this</code> from ClientXAConnection when
048: * it creates an instance of NetXAConnection. This is then
049: * passed on the underlying NetConnection constructor and is
050: * used to raise StatementEvents from any PreparedStatement that
051: * would be created from that NetConnection.
052: *
053: * @param netLogWriter NetLogWriter object associated with this connection
054: * @param user user id for this connection
055: * @param password password for this connection
056: * @param dataSource The DataSource object passed from the ClientXAConnection
057: * object from which this constructor was called
058: * @param rmId The Resource manager ID for XA Connections
059: * @param isXAConn true if this is a XA connection
060: * @param cpc The ClientPooledConnection object from which this
061: * NetConnection constructor was called. This is used
062: * to pass StatementEvents back to the pooledConnection
063: * object
064: * @throws SqlException
065: *
066: */
067: public NetXAConnection(NetLogWriter netLogWriter, String user,
068: String password,
069: org.apache.derby.jdbc.ClientBaseDataSource dataSource,
070: int rmId, boolean isXAConn, ClientPooledConnection cpc)
071: throws SqlException {
072: netCon = createNetConnection(netLogWriter, user, password,
073: dataSource, rmId, isXAConn, cpc);
074: checkPlatformVersion();
075: }
076:
077: protected void finalize() throws java.lang.Throwable {
078: netCon.finalize();
079: }
080:
081: public void setCorrelatorToken(byte[] crttoken) {
082: netCon.crrtkn_ = crttoken;
083: }
084:
085: public byte[] getCorrelatorToken() {
086: return netCon.crrtkn_;
087: }
088:
089: void setNetXAResource(NetXAResource xares) {
090: netCon.xares_ = xares;
091: }
092:
093: public void writeLocalXAStart_() throws SqlException {
094: netCon.netAgent_.netConnectionRequest_
095: .writeLocalXAStart(netCon);
096: }
097:
098: public void readLocalXAStart_() throws SqlException {
099: netCon.netAgent_.netConnectionReply_.readLocalXAStart(netCon);
100: }
101:
102: public void writeLocalXACommit_() throws SqlException {
103: netCon.netAgent_.netConnectionRequest_
104: .writeLocalXACommit(netCon);
105: }
106:
107: public void readLocalXACommit_() throws SqlException {
108: netCon.netAgent_.netConnectionReply_.readLocalXACommit(netCon);
109: }
110:
111: public void writeLocalXARollback_() throws SqlException {
112: netCon.netAgent_.netConnectionRequest_
113: .writeLocalXARollback(netCon);
114: }
115:
116: public void readLocalXARollback_() throws SqlException {
117: netCon.netAgent_.netConnectionReply_
118: .readLocalXARollback(netCon);
119: }
120:
121: public void writeTransactionStart(Statement statement)
122: throws SqlException {
123: //KATHEY remove below after checking that we don't need it.
124: if (!netCon.isXAConnection()) {
125: return; // not a XA connection
126: }
127:
128: // this is a XA connection
129: int xaState = netCon.getXAState();
130: netCon.xares_.exceptionsOnXA = null;
131: //TODO: Looks like this can go and also the whole client indoubtTransaction code.
132: /*
133: if (xaState == XA_RECOVER) { // in recover, clean up and go to open-idle
134: if (indoubtTransactions_ != null) {
135: indoubtTransactions_.clear();
136: indoubtTransactions_ = null;
137: setXAState(XA_OPEN_IDLE);
138: xaState = XA_OPEN_IDLE;
139: }
140:
141: }*/
142: // For derby we don't need to write transaction start for a local
143: //transaction. If autocommit is off we are good to go.
144: return;
145: }
146:
147: public byte[] getUOWID(Xid xid) {
148: NetIndoubtTransaction indoubtTxn = (NetIndoubtTransaction) netCon.indoubtTransactions_
149: .get(xid);
150: if (indoubtTxn == null) {
151: return null;
152: }
153: byte[] uowid = indoubtTxn.getUOWID();
154: return uowid;
155: }
156:
157: public int getPort(Xid xid) {
158: NetIndoubtTransaction indoubtTxn = (NetIndoubtTransaction) netCon.indoubtTransactions_
159: .get(xid);
160: if (indoubtTxn == null) {
161: return -1;
162: }
163: return indoubtTxn.getPort();
164: }
165:
166: public void writeCommit() throws SqlException {
167: // this logic must be in sync with willAutoCommitGenerateFlow() logic
168: int xaState = netCon.getXAState();
169: if (xaState == netCon.XA_T0_NOT_ASSOCIATED) {
170: netCon.xares_.callInfoArray_[netCon.xares_.conn_.currXACallInfoOffset_].xid_ = NetXAResource.nullXid;
171: writeLocalXACommit_();
172: }
173: }
174:
175: public void readCommit() throws SqlException {
176: int xaState = netCon.getXAState();
177: NetXACallInfo callInfo = netCon.xares_.callInfoArray_[netCon.currXACallInfoOffset_];
178: callInfo.xaRetVal_ = XAResource.XA_OK; // initialize XARETVAL
179: if (xaState == netCon.XA_T0_NOT_ASSOCIATED) {
180: readLocalXACommit_();
181: //TODO: Remove
182: //setXAState(XA_LOCAL);
183: }
184: if (callInfo.xaRetVal_ != XAResource.XA_OK) { // xaRetVal has possible error, format it
185: callInfo.xaFunction_ = NetXAResource.XAFUNC_COMMIT;
186: netCon.xares_.xaRetValErrorAccumSQL(callInfo, 0);
187: callInfo.xaRetVal_ = XAResource.XA_OK; // re-initialize XARETVAL
188: throw netCon.xares_.exceptionsOnXA;
189: }
190: }
191:
192: public void writeRollback() throws SqlException {
193: netCon.xares_.callInfoArray_[netCon.xares_.conn_.currXACallInfoOffset_].xid_ = netCon.xares_.nullXid;
194: writeLocalXARollback_();
195: }
196:
197: public void readRollback() throws SqlException {
198: NetXACallInfo callInfo = netCon.xares_.callInfoArray_[netCon.currXACallInfoOffset_];
199: callInfo.xaRetVal_ = XAResource.XA_OK; // initialize XARETVAL
200: readLocalXARollback_();
201:
202: if (callInfo.xaRetVal_ != XAResource.XA_OK) { // xaRetVal has possible error, format it
203: callInfo.xaFunction_ = NetXAResource.XAFUNC_ROLLBACK;
204: netCon.xares_.xaRetValErrorAccumSQL(callInfo, 0);
205: callInfo.xaRetVal_ = XAResource.XA_OK; // re-initialize XARETVAL
206: throw netCon.xares_.exceptionsOnXA;
207: }
208:
209: // for all XA connectiions
210: // TODO:KATHEY - Do we need this?
211: netCon.setXAState(netCon.XA_T0_NOT_ASSOCIATED);
212: }
213:
214: /**
215: * Returns underlying net connection
216: * @return NetConnection
217: */
218: public NetConnection getNetConnection() {
219: return netCon;
220: }
221:
222: private void checkPlatformVersion() throws SqlException {
223: int supportedVersion;
224:
225: supportedVersion = 8;
226:
227: if (netCon.xaHostVersion_ >= supportedVersion) {
228: // supported version, return
229: return;
230: }
231:
232: // unsupported version for platform
233: String platform = null;
234: platform = "Linux, Unix, Windows";
235: throw new SqlException(netCon.agent_.logWriter_,
236: new ClientMessageId(SQLState.NET_WRONG_XA_VERSION),
237: platform, new Integer(supportedVersion), new Integer(
238: netCon.xaHostVersion_));
239: }
240:
241: /**
242: *
243: * Creates NetConnection for the supported version of jdbc.
244: * This method can be overwritten to return NetConnection
245: * of the supported jdbc version.
246: * @param netLogWriter NetLogWriter object associated with this connection
247: * @param user user id for this connection
248: * @param password password for this connection
249: * @param dataSource The DataSource object passed from the ClientXAConnection
250: * object from which this constructor was called
251: * @param rmId The Resource manager ID for XA Connections
252: * @param isXAConn true if this is a XA connection
253: * @param cpc The ClientPooledConnection object from which this
254: * NetConnection constructor was called. This is used
255: * to pass StatementEvents back to the pooledConnection
256: * object
257: * @return NetConnection
258: *
259: */
260: protected NetConnection createNetConnection(
261: NetLogWriter netLogWriter, String user, String password,
262: org.apache.derby.jdbc.ClientBaseDataSource dataSource,
263: int rmId, boolean isXAConn, ClientPooledConnection cpc)
264: throws SqlException {
265: return (NetConnection) ClientDriver.getFactory()
266: .newNetConnection(netLogWriter, user, password,
267: dataSource, rmId, isXAConn, cpc);
268: }
269: }
|