1 | /* |
2 | |
3 | Derby - Class org.apache.derby.client.net.NetXAConnection |
4 | |
5 | Copyright (c) 2001, 2005, 2006 The Apache Software Foundation or its |
6 | licensors, where applicable. |
7 | |
8 | Licensed under the Apache License, Version 2.0 (the "License"); |
9 | you may not use this file except in compliance with the License. |
10 | You may obtain a copy of the License at |
11 | |
12 | http://www.apache.org/licenses/LICENSE-2.0 |
13 | |
14 | Unless required by applicable law or agreed to in writing, software |
15 | distributed under the License is distributed on an "AS IS" BASIS, |
16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
17 | See the License for the specific language governing permissions and |
18 | limitations under the License. |
19 | |
20 | */ |
21 | |
22 | package org.apache.derby.client.net; |
23 | |
24 | import java.sql.SQLException; |
25 | |
26 | import javax.transaction.xa.XAException; |
27 | import javax.transaction.xa.XAResource; |
28 | import javax.transaction.xa.Xid; |
29 | |
30 | import org.apache.derby.client.am.SqlException; |
31 | import org.apache.derby.client.am.Statement; |
32 | |
33 | import org.apache.derby.client.ClientPooledConnection; |
34 | import org.apache.derby.client.am.ClientMessageId; |
35 | import org.apache.derby.shared.common.reference.SQLState; |
36 | |
37 | import org.apache.derby.jdbc.ClientDriver; |
38 | |
39 | public class NetXAConnection { |
40 | private NetConnection netCon; |
41 | //---------------------constructors/finalizer--------------------------------- |
42 | // For XA Connections |
43 | /** |
44 | * |
45 | * The construcor for the NetXAConnection. The parameter |
46 | * is set to <code>this</code> from ClientXAConnection when |
47 | * it creates an instance of NetXAConnection. This is then |
48 | * passed on the underlying NetConnection constructor and is |
49 | * used to raise StatementEvents from any PreparedStatement that |
50 | * would be created from that NetConnection. |
51 | * |
52 | * @param netLogWriter NetLogWriter object associated with this connection |
53 | * @param user user id for this connection |
54 | * @param password password for this connection |
55 | * @param dataSource The DataSource object passed from the ClientXAConnection |
56 | * object from which this constructor was called |
57 | * @param rmId The Resource manager ID for XA Connections |
58 | * @param isXAConn true if this is a XA connection |
59 | * @param cpc The ClientPooledConnection object from which this |
60 | * NetConnection constructor was called. This is used |
61 | * to pass StatementEvents back to the pooledConnection |
62 | * object |
63 | * @throws SqlException |
64 | * |
65 | */ |
66 | public NetXAConnection(NetLogWriter netLogWriter, |
67 | String user, |
68 | String password, |
69 | org.apache.derby.jdbc.ClientBaseDataSource dataSource, |
70 | int rmId, |
71 | boolean isXAConn, |
72 | ClientPooledConnection cpc) throws SqlException { |
73 | netCon = createNetConnection (netLogWriter, user, password, |
74 | dataSource, rmId, isXAConn,cpc); |
75 | checkPlatformVersion(); |
76 | } |
77 | |
78 | protected void finalize() throws java.lang.Throwable { |
79 | netCon.finalize(); |
80 | } |
81 | |
82 | public void setCorrelatorToken(byte[] crttoken) { |
83 | netCon.crrtkn_ = crttoken; |
84 | } |
85 | |
86 | public byte[] getCorrelatorToken() { |
87 | return netCon.crrtkn_; |
88 | } |
89 | |
90 | void setNetXAResource(NetXAResource xares) { |
91 | netCon.xares_ = xares; |
92 | } |
93 | |
94 | public void writeLocalXAStart_() throws SqlException { |
95 | netCon.netAgent_.netConnectionRequest_.writeLocalXAStart(netCon); |
96 | } |
97 | |
98 | public void readLocalXAStart_() throws SqlException { |
99 | netCon.netAgent_.netConnectionReply_.readLocalXAStart(netCon); |
100 | } |
101 | |
102 | public void writeLocalXACommit_() throws SqlException { |
103 | netCon.netAgent_.netConnectionRequest_.writeLocalXACommit(netCon); |
104 | } |
105 | |
106 | public void readLocalXACommit_() throws SqlException { |
107 | netCon.netAgent_.netConnectionReply_.readLocalXACommit(netCon); |
108 | } |
109 | |
110 | public void writeLocalXARollback_() throws SqlException { |
111 | netCon.netAgent_.netConnectionRequest_.writeLocalXARollback(netCon); |
112 | } |
113 | |
114 | public void readLocalXARollback_() throws SqlException { |
115 | netCon.netAgent_.netConnectionReply_.readLocalXARollback(netCon); |
116 | } |
117 | |
118 | public void writeTransactionStart(Statement statement) throws SqlException { |
119 | //KATHEY remove below after checking that we don't need it. |
120 | if (!netCon.isXAConnection()) { |
121 | return; // not a XA connection |
122 | } |
123 | |
124 | // this is a XA connection |
125 | int xaState = netCon.getXAState(); |
126 | netCon.xares_.exceptionsOnXA = null; |
127 | //TODO: Looks like this can go and also the whole client indoubtTransaction code. |
128 | /* |
129 | if (xaState == XA_RECOVER) { // in recover, clean up and go to open-idle |
130 | if (indoubtTransactions_ != null) { |
131 | indoubtTransactions_.clear(); |
132 | indoubtTransactions_ = null; |
133 | setXAState(XA_OPEN_IDLE); |
134 | xaState = XA_OPEN_IDLE; |
135 | } |
136 | |
137 | }*/ |
138 | // For derby we don't need to write transaction start for a local |
139 | //transaction. If autocommit is off we are good to go. |
140 | return; |
141 | } |
142 | |
143 | public byte[] getUOWID(Xid xid) { |
144 | NetIndoubtTransaction indoubtTxn = |
145 | (NetIndoubtTransaction) netCon.indoubtTransactions_.get(xid); |
146 | if (indoubtTxn == null) { |
147 | return null; |
148 | } |
149 | byte[] uowid = indoubtTxn.getUOWID(); |
150 | return uowid; |
151 | } |
152 | |
153 | public int getPort(Xid xid) { |
154 | NetIndoubtTransaction indoubtTxn = (NetIndoubtTransaction) netCon.indoubtTransactions_.get(xid); |
155 | if (indoubtTxn == null) { |
156 | return -1; |
157 | } |
158 | return indoubtTxn.getPort(); |
159 | } |
160 | |
161 | public void writeCommit() throws SqlException { |
162 | // this logic must be in sync with willAutoCommitGenerateFlow() logic |
163 | int xaState = netCon.getXAState(); |
164 | if (xaState == netCon.XA_T0_NOT_ASSOCIATED){ |
165 | netCon.xares_.callInfoArray_[ |
166 | netCon.xares_.conn_.currXACallInfoOffset_ |
167 | ].xid_ = NetXAResource.nullXid; |
168 | writeLocalXACommit_(); |
169 | } |
170 | } |
171 | |
172 | public void readCommit() throws SqlException { |
173 | int xaState = netCon.getXAState(); |
174 | NetXACallInfo callInfo = netCon.xares_.callInfoArray_ |
175 | [netCon.currXACallInfoOffset_]; |
176 | callInfo.xaRetVal_ = XAResource.XA_OK; // initialize XARETVAL |
177 | if (xaState == netCon.XA_T0_NOT_ASSOCIATED) { |
178 | readLocalXACommit_(); |
179 | //TODO: Remove |
180 | //setXAState(XA_LOCAL); |
181 | } |
182 | if (callInfo.xaRetVal_ != XAResource.XA_OK) { // xaRetVal has possible error, format it |
183 | callInfo.xaFunction_ = NetXAResource.XAFUNC_COMMIT; |
184 | netCon.xares_.xaRetValErrorAccumSQL(callInfo, 0); |
185 | callInfo.xaRetVal_ = XAResource.XA_OK; // re-initialize XARETVAL |
186 | throw netCon.xares_.exceptionsOnXA; |
187 | } |
188 | } |
189 | |
190 | public void writeRollback() throws SqlException { |
191 | netCon.xares_.callInfoArray_[ |
192 | netCon.xares_.conn_.currXACallInfoOffset_ |
193 | ].xid_ = netCon.xares_.nullXid; |
194 | writeLocalXARollback_(); |
195 | } |
196 | |
197 | public void readRollback() throws SqlException { |
198 | NetXACallInfo callInfo = netCon.xares_.callInfoArray_ |
199 | [netCon.currXACallInfoOffset_]; |
200 | callInfo.xaRetVal_ = XAResource.XA_OK; // initialize XARETVAL |
201 | readLocalXARollback_(); |
202 | |
203 | if (callInfo.xaRetVal_ != XAResource.XA_OK) { // xaRetVal has possible error, format it |
204 | callInfo.xaFunction_ = NetXAResource.XAFUNC_ROLLBACK; |
205 | netCon.xares_.xaRetValErrorAccumSQL(callInfo, 0); |
206 | callInfo.xaRetVal_ = XAResource.XA_OK; // re-initialize XARETVAL |
207 | throw netCon.xares_.exceptionsOnXA; |
208 | } |
209 | |
210 | |
211 | // for all XA connectiions |
212 | // TODO:KATHEY - Do we need this? |
213 | netCon.setXAState(netCon.XA_T0_NOT_ASSOCIATED); |
214 | } |
215 | |
216 | /** |
217 | * Returns underlying net connection |
218 | * @return NetConnection |
219 | */ |
220 | public NetConnection getNetConnection () { |
221 | return netCon; |
222 | } |
223 | |
224 | private void checkPlatformVersion() throws SqlException { |
225 | int supportedVersion; |
226 | |
227 | supportedVersion = 8; |
228 | |
229 | if (netCon.xaHostVersion_ >= supportedVersion) { |
230 | // supported version, return |
231 | return; |
232 | } |
233 | |
234 | // unsupported version for platform |
235 | String platform = null; |
236 | platform = "Linux, Unix, Windows"; |
237 | throw new SqlException(netCon.agent_.logWriter_, |
238 | new ClientMessageId(SQLState.NET_WRONG_XA_VERSION), |
239 | platform, new Integer(supportedVersion), |
240 | new Integer(netCon.xaHostVersion_)); |
241 | } |
242 | |
243 | /** |
244 | * |
245 | * Creates NetConnection for the supported version of jdbc. |
246 | * This method can be overwritten to return NetConnection |
247 | * of the supported jdbc version. |
248 | * @param netLogWriter NetLogWriter object associated with this connection |
249 | * @param user user id for this connection |
250 | * @param password password for this connection |
251 | * @param dataSource The DataSource object passed from the ClientXAConnection |
252 | * object from which this constructor was called |
253 | * @param rmId The Resource manager ID for XA Connections |
254 | * @param isXAConn true if this is a XA connection |
255 | * @param cpc The ClientPooledConnection object from which this |
256 | * NetConnection constructor was called. This is used |
257 | * to pass StatementEvents back to the pooledConnection |
258 | * object |
259 | * @return NetConnection |
260 | * |
261 | */ |
262 | protected NetConnection createNetConnection (NetLogWriter netLogWriter, |
263 | String user, |
264 | String password, |
265 | org.apache.derby.jdbc.ClientBaseDataSource dataSource, |
266 | int rmId, |
267 | boolean isXAConn, |
268 | ClientPooledConnection cpc) throws SqlException { |
269 | return (NetConnection)ClientDriver.getFactory().newNetConnection |
270 | (netLogWriter, user, password,dataSource, rmId, isXAConn,cpc); |
271 | } |
272 | } |