KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > jdbc > XAStatementControl


1 /*
2
3    Derby - Class org.apache.derby.jdbc.XAStatementControl
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. 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.jdbc;
23
24 import org.apache.derby.iapi.jdbc.BrokeredConnection;
25 import org.apache.derby.iapi.jdbc.BrokeredStatementControl;
26 import org.apache.derby.iapi.jdbc.BrokeredStatement;
27 import org.apache.derby.iapi.jdbc.BrokeredPreparedStatement;
28 import org.apache.derby.iapi.jdbc.BrokeredCallableStatement;
29 import org.apache.derby.iapi.jdbc.EngineStatement;
30 import org.apache.derby.impl.jdbc.EmbedConnection;
31 import org.apache.derby.impl.jdbc.EmbedResultSet;
32 import org.apache.derby.impl.jdbc.EmbedStatement;
33 import org.apache.derby.impl.jdbc.EmbedPreparedStatement;
34
35 import java.sql.*;
36
37 /**
38     The Statement returned by an Connection returned by a XAConnection
39     needs to float across the underlying real connections. We do this by implementing
40     a wrapper statement.
41 */

42 final class XAStatementControl implements BrokeredStatementControl {
43
44     /**
45     */

46     private final EmbedXAConnection xaConnection;
47     private final BrokeredConnection applicationConnection;
48     BrokeredStatement applicationStatement;
49     private EmbedConnection realConnection;
50     private Statement realStatement;
51     private PreparedStatement realPreparedStatement;
52     private CallableStatement realCallableStatement;
53
54     private XAStatementControl(EmbedXAConnection xaConnection) {
55         this.xaConnection = xaConnection;
56         this.realConnection = xaConnection.realConnection;
57         this.applicationConnection = xaConnection.currentConnectionHandle;
58     }
59
60     XAStatementControl(EmbedXAConnection xaConnection,
61                                 Statement realStatement) throws SQLException {
62         this(xaConnection);
63         this.realStatement = realStatement;
64         this.applicationStatement = applicationConnection.newBrokeredStatement(this);
65         
66         ((EmbedStatement) realStatement).setApplicationStatement(
67                 applicationStatement);
68     }
69     XAStatementControl(EmbedXAConnection xaConnection,
70                 PreparedStatement realPreparedStatement,
71                 String JavaDoc sql, Object JavaDoc generatedKeys) throws SQLException {
72         this(xaConnection);
73         this.realPreparedStatement = realPreparedStatement;
74         this.applicationStatement = applicationConnection.newBrokeredStatement(this, sql, generatedKeys);
75         ((EmbedStatement) realPreparedStatement).setApplicationStatement(
76                 applicationStatement);
77     }
78     XAStatementControl(EmbedXAConnection xaConnection,
79                 CallableStatement realCallableStatement,
80                 String JavaDoc sql) throws SQLException {
81         this(xaConnection);
82         this.realCallableStatement = realCallableStatement;
83         this.applicationStatement = applicationConnection.newBrokeredStatement(this, sql);
84         ((EmbedStatement) realCallableStatement).setApplicationStatement(
85                 applicationStatement);
86     }
87
88     public Statement getRealStatement() throws SQLException {
89
90         //
91
if (applicationConnection == xaConnection.currentConnectionHandle) {
92
93             // Application connection is the same.
94
if (realConnection == xaConnection.realConnection)
95                 return realStatement;
96
97             // If we switched back to a local connection, and the first access is through
98
// a non-connection object (e.g. statement then realConnection will be null)
99
if (xaConnection.realConnection == null) {
100                 // force the connection
101
xaConnection.getRealConnection();
102             }
103
104             // underlying connection has changed.
105
// create new Statement
106
Statement newStatement = applicationStatement.createDuplicateStatement(xaConnection.realConnection, realStatement);
107             ((EmbedStatement) realStatement).transferBatch((EmbedStatement) newStatement);
108  
109             try {
110                 realStatement.close();
111             } catch (SQLException sqle) {
112             }
113
114             realStatement = newStatement;
115             realConnection = xaConnection.realConnection;
116             ((EmbedStatement) realStatement).setApplicationStatement(
117                     applicationStatement);
118         }
119         else {
120             // application connection is different, therefore the outer application
121
// statement is closed, so just return the realStatement. It should be
122
// closed by virtue of its application connection being closed.
123
}
124         return realStatement;
125     }
126
127     public PreparedStatement getRealPreparedStatement() throws SQLException {
128         //
129
if (applicationConnection == xaConnection.currentConnectionHandle) {
130             // Application connection is the same.
131
if (realConnection == xaConnection.realConnection)
132                 return realPreparedStatement;
133
134             // If we switched back to a local connection, and the first access is through
135
// a non-connection object (e.g. statement then realConnection will be null)
136
if (xaConnection.realConnection == null) {
137                 // force the connection
138
xaConnection.getRealConnection();
139             }
140
141             // underlying connection has changed.
142
// create new PreparedStatement
143
PreparedStatement newPreparedStatement =
144                 ((BrokeredPreparedStatement) applicationStatement).createDuplicateStatement(xaConnection.realConnection, realPreparedStatement);
145
146
147             // ((EmbedStatement) realPreparedStatement).transferBatch((EmbedStatement) newPreparedStatement);
148
((EmbedPreparedStatement) realPreparedStatement).transferParameters((EmbedPreparedStatement) newPreparedStatement);
149
150             try {
151                 realPreparedStatement.close();
152             } catch (SQLException sqle) {
153             }
154
155             realPreparedStatement = newPreparedStatement;
156             realConnection = xaConnection.realConnection;
157             ((EmbedStatement) realPreparedStatement).setApplicationStatement(
158                         applicationStatement);
159         }
160         else {
161             // application connection is different, therefore the outer application
162
// statement is closed, so just return the realStatement. It should be
163
// closed by virtue of its application connection being closed.
164
}
165         return realPreparedStatement;
166     }
167
168     public CallableStatement getRealCallableStatement() throws SQLException {
169         if (applicationConnection == xaConnection.currentConnectionHandle) {
170             // Application connection is the same.
171
if (realConnection == xaConnection.realConnection)
172                 return realCallableStatement;
173
174             // If we switched back to a local connection, and the first access is through
175
// a non-connection object (e.g. statement then realConnection will be null)
176
if (xaConnection.realConnection == null) {
177                 // force the connection
178
xaConnection.getRealConnection();
179             }
180
181             // underlying connection has changed.
182
// create new PreparedStatement
183
CallableStatement newCallableStatement =
184                 ((BrokeredCallableStatement) applicationStatement).createDuplicateStatement(xaConnection.realConnection, realCallableStatement);
185
186             ((EmbedStatement) realCallableStatement).transferBatch((EmbedStatement) newCallableStatement);
187
188             try {
189                 realCallableStatement.close();
190             } catch (SQLException sqle) {
191             }
192
193             realCallableStatement = newCallableStatement;
194             realConnection = xaConnection.realConnection;
195             ((EmbedStatement) realCallableStatement).setApplicationStatement(
196                     applicationStatement);
197         }
198         else {
199             // application connection is different, therefore the outer application
200
// statement is closed, so just return the realStatement. It should be
201
// closed by virtue of its application connection being closed.
202
}
203         return realCallableStatement;
204     }
205
206     /**
207      * Don't need to wrap the ResultSet but do need to update its
208      * application Statement reference to be the one the application
209      * used to create the ResultSet.
210      */

211     public ResultSet wrapResultSet(Statement s, ResultSet rs) {
212         if (rs != null)
213             ((EmbedResultSet) rs).setApplicationStatement(s);
214         return rs;
215     }
216
217     /**
218         Can cursors be held across commits.
219     */

220     public int checkHoldCursors(int holdability) throws SQLException {
221         return xaConnection.checkHoldCursors(holdability, true);
222     }
223 }
224
Popular Tags