001: /*
002:
003: Derby - Class org.apache.derbyTesting.functionTests.tests.lang. ConcurrentImplicitCreateSchema.java
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.derbyTesting.functionTests.tests.lang;
023:
024: import java.sql.Connection;
025: import java.sql.SQLException;
026: import java.sql.Statement;
027:
028: import org.apache.derby.tools.ij;
029:
030: /**
031: * Test for several threads creating tables in the same originally
032: * non-existing schema. This will cause an implicit creation of the
033: * schema. The test was created for the fix of JIRA issue DERBY-230
034: * where an error occurred if two threads try to create the schema in
035: * parallel.
036: *
037: * @author oystein.grovlen@sun.com
038: */
039:
040: public class ConcurrentImplicitCreateSchema {
041:
042: /**
043: * Runnable that will create and drop table.
044: */
045: class CreateTable implements Runnable {
046: /** Id of the thread running this instance */
047: private int myId;
048: /** Which schema to use */
049: private int schemaId;
050: /** Database connection for this thread */
051: private Connection conn = null;
052: /** Test object. Used to inform about failures. */
053: private ConcurrentImplicitCreateSchema test;
054:
055: CreateTable(int id, int schemaId,
056: ConcurrentImplicitCreateSchema test)
057: throws SQLException, IllegalAccessException,
058: ClassNotFoundException, InstantiationException {
059: this .myId = id;
060: this .schemaId = schemaId;
061: this .test = test;
062:
063: // Open a connection for this thread
064: conn = ij.startJBMS();
065: conn.setAutoCommit(false);
066: }
067:
068: public void run() {
069: try {
070: Statement s = conn.createStatement();
071: s.execute("create table testschema" + schemaId
072: + ".testtab" + myId
073: + "(num int, addr varchar(40))");
074: s.execute("drop table testschema" + schemaId
075: + ".testtab" + myId);
076: } catch (SQLException e) {
077: test.failed(e);
078: }
079:
080: // We should close the transaction regardless of outcome
081: // Otherwise, other threads may wait on transactional
082: // locks until this transaction times out.
083: try {
084: conn.commit();
085: conn.close();
086: } catch (SQLException e) {
087: test.failed(e);
088: }
089: // System.out.println("Thread " + myId + " completed.");
090: }
091: }
092:
093: /**
094: * Outcome of test.
095: * Will be set to false if any failure is detected.
096: */
097: boolean passed = true;
098:
099: public static void main(String[] args) {
100: new ConcurrentImplicitCreateSchema().go(args);
101: }
102:
103: void go(String[] args) {
104: System.out
105: .println("Test ConcurrentImplicitCreateSchema starting");
106:
107: try {
108: // Load the JDBC Driver class
109: // use the ij utility to read the property file and
110: // make the initial connection.
111: ij.getPropertyArg(args);
112: Connection conn = ij.startJBMS();
113:
114: conn.setAutoCommit(true);
115:
116: // Drop the schemas we will be using in case they exist.
117: // This will ensure that they are implicitly created by this test
118: Statement s = conn.createStatement();
119:
120: // Number of schemas to use. An equal number of threads
121: // will operate on each schema.
122: final int NSCHEMAS = 1;
123:
124: for (int i = 0; i < NSCHEMAS; ++i) {
125: try {
126: s.execute("drop schema testschema" + i
127: + " restrict");
128: } catch (SQLException e) {
129: if (e.getSQLState().equals("42Y07")) {
130: // IGNORE. Schema did not exist. That is our target.
131: } else {
132: throw e;
133: }
134: }
135: }
136:
137: // Number of threads to run.
138: final int NTHREADS = 100;
139:
140: // Create threads
141: Thread[] threads = new Thread[NTHREADS];
142: for (int i = 0; i < NTHREADS; ++i) {
143: threads[i] = new Thread(new CreateTable(i,
144: i % NSCHEMAS, this ));
145: }
146:
147: // Start threads
148: for (int i = 0; i < NTHREADS; ++i) {
149: threads[i].start();
150: }
151:
152: // Wait for threads to complete
153: for (int i = 0; i < NTHREADS; ++i) {
154: threads[i].join();
155: }
156:
157: conn.close();
158: System.out.println("Closed connection");
159: } catch (Throwable e) {
160: System.out.println("exception thrown:");
161: failed(e);
162: }
163:
164: System.out.print("Test ConcurrentImplicitCreateSchema ");
165: if (passed) {
166: System.out.println("PASSED");
167: } else {
168: System.out.println("FAILED");
169: }
170: }
171:
172: void failed(Throwable e) {
173: if (e instanceof SQLException) {
174: printSQLError((SQLException) e);
175: } else {
176: e.printStackTrace();
177: }
178: passed = false;
179: }
180:
181: void printSQLError(SQLException e) {
182: while (e != null) {
183: System.out.println(e.toString());
184: e.printStackTrace();
185: e = e.getNextException();
186: }
187: }
188: }
|