KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derbyTesting > functionTests > tests > lang > deadlockMode


1 /*
2
3    Derby - Class org.apache.derbyTesting.functionTests.tests.lang.deadlockMode
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.derbyTesting.functionTests.tests.lang;
23
24 import java.sql.Connection JavaDoc;
25 import java.sql.DriverManager JavaDoc;
26 import java.sql.Statement JavaDoc;
27 import java.sql.PreparedStatement JavaDoc;
28 import java.sql.ResultSet JavaDoc;
29 import java.sql.ResultSetMetaData JavaDoc;
30 import java.sql.SQLException JavaDoc;
31 import java.sql.SQLWarning JavaDoc;
32
33 import org.apache.derby.tools.ij;
34 import org.apache.derby.tools.JDBCDisplayUtil;
35
36 /**
37     This tests for deadlock which can occur if two threads get a
38     row lock before getting a table lock on the same table. This can
39     happen if the lock obtained by the insert, update or delete result set
40     is a smaller range than the table scan result set. The insert, update or
41     delete result set lock is obtained first. For example, if the insert, update
42     or delete result set obtain a row lock and then the table scan obtains a
43     table scan lock, deadlock can occur since two threads can obtain the row lock
44     and then both thread will want the same table lock.
45  */

46
47 public class deadlockMode {
48
49     private static final int THREAD_COUNT = 20;
50     private static boolean passed = false;
51     private Object JavaDoc syncObject = new Object JavaDoc();
52     private int doneCount;
53     private deadlockMode() {}
54
55     public static void main(String JavaDoc[] args) {
56         System.out.println("Test deadlockMode starting");
57         
58         deadlockMode tester = new deadlockMode();
59
60         try {
61             // use the ij utility to read the property file and
62
// make the initial connection.
63
ij.getPropertyArg(args);
64             Connection JavaDoc conn = ij.startJBMS();
65
66             setup(conn, true);
67             passed = true;
68             tester.runtest();
69             teardown(conn);
70             conn.close();
71
72
73         } catch (Throwable JavaDoc e) {
74             System.out.println("FAIL: exception thrown:");
75             passed = false;
76             JDBCDisplayUtil.ShowException(System.out,e);
77             e.printStackTrace();
78         }
79
80         if (passed)
81             System.out.println("PASS");
82         System.out.println("Test cursor finished");
83     }
84     /**
85      * This method creates THREAD_COUNT threads which will all try to
86      * update the same table
87      */

88     private void runtest() throws InterruptedException JavaDoc
89     {
90         Thread JavaDoc [] t = new Thread JavaDoc[THREAD_COUNT];
91         for (int i = 0; i < THREAD_COUNT; i++)
92         {
93             t[i] = new Thread JavaDoc(new Runnable JavaDoc() {
94                 public void run() {startnew(); }});
95             t[i].start();
96         }
97         boolean notdone = true;
98         while(notdone)
99         {
100             synchronized(syncObject)
101             {
102                 if (doneCount == THREAD_COUNT)
103                     notdone = false;
104                 else
105                     syncObject.wait();
106             }
107         }
108     }
109     /**
110      * Keep track of how many are done so we can wait until all the
111      * threads are finished before saying we have passed
112      */

113     private void done()
114     {
115         System.out.println("Done Thread");
116         synchronized(syncObject)
117         {
118             doneCount++;
119             syncObject.notify();
120         }
121     }
122     /**
123      * This method creates a connection, loads the query into cache using
124      * READ_COMMITTED and then tries to execute the query using SERIALIZABLE.
125      * If we don't update the lock mode based on the isolation level at
126      * execution time, the query can deadlock with other threads
127      * SERALIZABLE requires a table lock mode. READ_COMMITTED uses a row lock.
128      */

129     private void startnew()
130     {
131         Connection JavaDoc conn = null;
132         try {
133             // make the initial connection.
134
conn = ij.startJBMS();
135             System.out.println("Starting thread");
136
137             Statement JavaDoc stmt = conn.createStatement();
138             // execute a query to load cache
139
stmt.executeUpdate("update t set i = 456 where i = 456");
140             // set isolation level to serializable
141
conn.setAutoCommit(false);
142             stmt.execute("set isolation serializable");
143             for (int i = 0; i < 100 ; i++)
144             {
145                 stmt.executeUpdate("update t set i = 456 where i = 456");
146                 conn.commit();
147             }
148             done();
149             
150         } catch (Throwable JavaDoc e) {
151             synchronized(syncObject)
152             {
153                 System.out.println("FAIL: exception thrown:");
154                 passed = false;
155                 JDBCDisplayUtil.ShowException(System.out,e);
156                 e.printStackTrace();
157                 done();
158             }
159         }
160         finally {
161             try {
162                 if (conn != null) {
163                     conn.rollback();
164                     conn.close();
165                 }
166             } catch (SQLException JavaDoc sqle) {
167                 System.out.println("FAIL: exception thrown:");
168                 passed = false;
169                 JDBCDisplayUtil.ShowException(System.out,sqle);
170                 sqle.printStackTrace();
171             }
172         }
173     }
174     /**
175      * set up the table for the test
176      */

177     static void setup(Connection JavaDoc conn, boolean first) throws SQLException JavaDoc {
178         Statement JavaDoc stmt = conn.createStatement();
179
180         if (first) {
181             verifyCount(
182                 stmt.executeUpdate("create table t (i int)"),
183                 0);
184
185         } else {
186             verifyBoolean(
187                 stmt.execute("delete from t"),
188                 false);
189         }
190
191         verifyCount(
192             stmt.executeUpdate("insert into t values (1956)"),
193             1);
194
195         verifyCount(
196             stmt.executeUpdate("insert into t values (456)"),
197             1);
198
199         verifyCount(
200             stmt.executeUpdate("insert into t values (180)"),
201             1);
202
203         verifyCount(
204             stmt.executeUpdate("insert into t values (3)"),
205             1);
206
207         stmt.close();
208
209         System.out.println("PASS: setup complete");
210     }
211
212     /**
213      * clean up
214      */

215     static void teardown(Connection JavaDoc conn) throws SQLException JavaDoc {
216         Statement JavaDoc stmt = conn.createStatement();
217
218         verifyCount(
219             stmt.executeUpdate("drop table t"),
220             0);
221
222         stmt.close();
223
224         System.out.println("PASS: teardown complete");
225     }
226     /**
227      * verify row count
228      */

229     static void verifyCount(int count, int expect) throws SQLException JavaDoc {
230         if (count!=expect) {
231             System.out.println("FAIL: Expected "+expect+" got "+count+" rows");
232             throw new SQLException JavaDoc("Wrong number of rows returned");
233         }
234         else
235             System.out.println("PASS: expected and got "+count+
236                                (count == 1? " row":" rows"));
237     }
238
239     /**
240      * verify boolean value
241      */

242     static void verifyBoolean(boolean got, boolean expect) throws SQLException JavaDoc {
243         if (got!=expect) {
244             System.out.println("FAIL: Expected "+expect+" got "+got);
245             throw new SQLException JavaDoc("Wrong boolean returned");
246         }
247         else
248             System.out.println("PASS: expected and got "+got);
249     }
250 }
251
Popular Tags