001: /*
002:
003: Derby - Class org.apache.derby.diag.TransactionTable
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.diag;
023:
024: import org.apache.derby.iapi.services.monitor.Monitor;
025: import org.apache.derby.iapi.services.sanity.SanityManager;
026:
027: import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
028: import org.apache.derby.iapi.sql.conn.ConnectionUtil;
029: import org.apache.derby.iapi.store.access.AccessFactory;
030: import org.apache.derby.iapi.store.access.TransactionInfo;
031:
032: import org.apache.derby.vti.VTITemplate;
033: import org.apache.derby.vti.VTICosting;
034: import org.apache.derby.vti.VTIEnvironment;
035:
036: import org.apache.derby.iapi.sql.ResultColumnDescriptor;
037: import org.apache.derby.impl.jdbc.EmbedResultSetMetaData;
038:
039: import org.apache.derby.iapi.reference.Limits;
040: import org.apache.derby.iapi.util.StringUtil;
041:
042: import java.sql.ResultSetMetaData;
043: import java.sql.SQLException;
044: import java.sql.Types;
045:
046: /**
047:
048:
049: TransactionTable is a virtual table that shows all transactions
050: currently in the database.
051:
052: This virtual table can be invoked by calling it
053: directly
054: <PRE> select * from SYSCS_DIAG.TRANSACTION_TABLE </PRE>
055:
056: <P>The TransactionTable virtual table takes a snap shot of the
057: transaction table while the system is in flux, so it is possible that some
058: transactions may be in transition state while the snap shot is taken.
059: We choose to do this rather then impose extraneous timing restrictions so
060: that the use of this tool will not alter the normal timing and flow of
061: execution in the application.
062:
063: <P>The TransactionTable virtual table has the following columns:
064: <UL>
065: <LI>XID varchar(15) - not nullable. The transaction id, this can be joined
066: with the LockTable virtual table's XID.</LI>
067: <LI>GLOBAL_XID varchar(140) - nullable. The global transaction id, only
068: set if this transaction is a participant in a distributed transaction.</LI>
069: <LI>USERNAME varchar(128) - nullable. The user name, or APP by default.
070: May appear null if the transaction is started by Cloudscape.</LI>
071: <LI>TYPE varchar(30) - not nullable. UserTransaction or an internal
072: transaction spawned by Cloudscape.</LI>
073: <LI>STATUS varchar(8) - not nullable. IDLE or ACTIVE. A transaction is
074: IDLE only when it is first created or right after it commits. Any
075: transaction that holds or has held any resource in the database is ACTIVE.
076: Accessing the TransactionTable virtual table without using the class alias
077: will not activate the transaction.</LI>
078: <LI>FIRST_INSTANT varchar(20) - nullable. If null, this is a read only
079: transaction. If not null, this is the first log record instant written by
080: the transaction.</LI>
081: <LI>SQL_TEXT VARCHAR(32672) - nullable. if null, this transaction is
082: currently not being executed in the database. If not null, this is the SQL
083: statement currently being executed in the database.</LI>
084: </UL>
085: */
086: public class TransactionTable extends VTITemplate implements VTICosting {
087:
088: private TransactionInfo[] transactionTable;
089: boolean initialized;
090: int currentRow;
091: private boolean wasNull;
092:
093: /**
094: @see java.sql.ResultSet#getMetaData
095: */
096: public ResultSetMetaData getMetaData() {
097: return metadata;
098: }
099:
100: /**
101: @see java.sql.ResultSet#next
102: @exception SQLException if no transaction context can be found
103: */
104: public boolean next() throws SQLException {
105: if (!initialized) {
106: LanguageConnectionContext lcc = ConnectionUtil
107: .getCurrentLCC();
108:
109: AccessFactory af = lcc.getLanguageConnectionFactory()
110: .getAccessFactory();
111: transactionTable = af.getTransactionInfo();
112:
113: initialized = true;
114: currentRow = -1;
115: }
116:
117: if (transactionTable == null)
118: return false;
119:
120: for (currentRow++; currentRow < transactionTable.length; currentRow++) {
121: TransactionInfo info = transactionTable[currentRow];
122: if (info == null)
123: continue; // transaction object in flux while the
124: // snap shot was taken, get another row
125: return true;
126: }
127:
128: // currentRow >= transactionTable.length
129: transactionTable = null;
130: return false;
131: }
132:
133: /**
134: @see java.sql.ResultSet#close
135: */
136: public void close() {
137: transactionTable = null;
138: }
139:
140: /**
141: All columns in TransactionTable VTI is of String type.
142: @see java.sql.ResultSet#getString
143: */
144: public String getString(int columnNumber) {
145: TransactionInfo info = transactionTable[currentRow];
146: String str = null;
147:
148: switch (columnNumber) {
149: case 1:
150: str = info.getTransactionIdString();
151: break;
152:
153: case 2:
154: str = info.getGlobalTransactionIdString();
155: break;
156:
157: case 3:
158: str = info.getUsernameString();
159: break;
160:
161: case 4:
162: str = info.getTransactionTypeString();
163: break;
164:
165: case 5:
166: str = info.getTransactionStatusString();
167: break;
168:
169: case 6:
170: str = info.getFirstLogInstantString();
171: break;
172:
173: case 7:
174:
175: str = info.getStatementTextString();
176: str = StringUtil.truncate(str, Limits.DB2_VARCHAR_MAXWIDTH);
177: break;
178:
179: default:
180: str = null;
181: }
182:
183: wasNull = (str == null);
184: return str;
185:
186: }
187:
188: /**
189: @see java.sql.ResultSet#wasNull
190: */
191: public boolean wasNull() {
192: return wasNull;
193: }
194:
195: /** VTI costing interface */
196:
197: /**
198: @see VTICosting#getEstimatedRowCount
199: */
200: public double getEstimatedRowCount(VTIEnvironment vtiEnvironment) {
201: return VTICosting.defaultEstimatedRowCount;
202: }
203:
204: /**
205: @see VTICosting#getEstimatedCostPerInstantiation
206: */
207: public double getEstimatedCostPerInstantiation(
208: VTIEnvironment vtiEnvironment) {
209: return VTICosting.defaultEstimatedCost;
210: }
211:
212: /**
213: @return false
214: @see VTICosting#supportsMultipleInstantiations
215: */
216: public boolean supportsMultipleInstantiations(
217: VTIEnvironment vtiEnvironment) {
218: return false;
219: }
220:
221: /*
222: ** Metadata
223: */
224: private static final ResultColumnDescriptor[] columnInfo = {
225:
226: EmbedResultSetMetaData.getResultColumnDescriptor("XID",
227: Types.VARCHAR, false, 15),
228: EmbedResultSetMetaData.getResultColumnDescriptor(
229: "GLOBAL_XID", Types.VARCHAR, true, 140),
230: EmbedResultSetMetaData.getResultColumnDescriptor(
231: "USERNAME", Types.VARCHAR, true, 128),
232: EmbedResultSetMetaData.getResultColumnDescriptor("TYPE",
233: Types.VARCHAR, false, 30),
234: EmbedResultSetMetaData.getResultColumnDescriptor("STATUS",
235: Types.VARCHAR, false, 8),
236: EmbedResultSetMetaData.getResultColumnDescriptor(
237: "FIRST_INSTANT", Types.VARCHAR, true, 20),
238: EmbedResultSetMetaData.getResultColumnDescriptor(
239: "SQL_TEXT", Types.VARCHAR, true,
240: Limits.DB2_VARCHAR_MAXWIDTH), };
241:
242: private static final ResultSetMetaData metadata = new EmbedResultSetMetaData(
243: columnInfo);
244: }
|