| /* |
| |
| Derby - Class org.apache.derbyTesting.functionTests.tests.lang.UniqueConstraintMultiThreadedTest |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| */ |
| |
| package org.apache.derbyTesting.functionTests.tests.lang; |
| |
| import java.sql.Connection; |
| import java.sql.PreparedStatement; |
| import java.sql.Statement; |
| import junit.framework.Test; |
| import org.apache.derbyTesting.junit.BaseJDBCTestCase; |
| import org.apache.derbyTesting.junit.BaseTestSuite; |
| import org.apache.derbyTesting.junit.TestConfiguration; |
| |
| public class UniqueConstraintMultiThreadedTest extends BaseJDBCTestCase { |
| |
| public UniqueConstraintMultiThreadedTest() { |
| super ("Multi Threaded Unique Constraint Test"); |
| } |
| |
| /** |
| * Deletes a record in a transaction and tries to insert the same |
| * from a different transaction. Once second transaction goes on wait |
| * first transaction is committed or rolled back based on third |
| * param (boolean commit). |
| * |
| * @param isolation1 isolation level for 1st thread |
| * @param isolation2 isolation level for 2nd thread |
| * @param commit whether or not to commit |
| */ |
| private void executeThreads (int isolation1, int isolation2, |
| boolean commit) throws Exception { |
| Connection con1 = openDefaultConnection(); |
| con1.setTransactionIsolation(isolation1); |
| Connection con2 = openDefaultConnection(); |
| try { |
| con2.setTransactionIsolation(isolation2); |
| DBOperations dbo1 = new DBOperations (con1, 5); |
| DBOperations dbo2 = new DBOperations (con2, 5); |
| dbo1.delete(); |
| Thread t = new Thread (dbo2); |
| t.start(); |
| //wait for 2 sec should be enough for dbo2 so on wait |
| t.sleep(2000); |
| if (commit) { |
| dbo1.rollback(); |
| t.join(); |
| assertSQLState("isolation levels: " + isolation1 |
| + " " + isolation2, "23505", dbo2.getException()); |
| } |
| else { |
| dbo1.commit(); |
| t.join(); |
| assertNull("isolation levels: " + isolation1 |
| + " " + isolation2, dbo2.getException()); |
| } |
| assertNull("unexpected failure: " + isolation1 |
| + " " + isolation2, dbo2.getUnexpectedException()); |
| } |
| finally { |
| con1.commit(); |
| con2.commit(); |
| con1.close(); |
| con2.close(); |
| } |
| |
| } |
| |
| /** |
| * Test inserting a duplicate record while original is deleted in |
| * a transaction and later committed. |
| */ |
| public void testLockingWithcommit () throws Exception { |
| for (int i = 0; i < 4; i++) { |
| for (int j = 0; j < 4; j++) { |
| executeThreads((int) Math.pow(2,i), |
| (int) Math.pow (2,j), true); |
| } |
| } |
| } |
| |
| /** |
| * Test inserting a duplicate record while original is deleted in |
| * a transaction and later rolled back. |
| */ |
| public void testLockingWithRollback () throws Exception { |
| for (int i = 0; i < 4; i++) { |
| for (int j = 0; j < 4; j++) { |
| executeThreads((int) Math.pow (2,i), |
| (int) Math.pow (2,j), false); |
| } |
| } |
| } |
| |
| public static Test suite() { |
| BaseTestSuite suite = new BaseTestSuite("UniqueConstraintTest"); |
| suite.addTest(TestConfiguration.embeddedSuite(UniqueConstraintMultiThreadedTest.class)); |
| return suite; |
| } |
| |
| protected void setUp() throws Exception { |
| Statement stmt = createStatement(); |
| stmt.execute("create table tab1 (i integer)"); |
| stmt.executeUpdate("alter table tab1 add constraint con1 unique (i)"); |
| PreparedStatement ps = prepareStatement("insert into tab1 " + |
| "values (?)"); |
| for (int i = 0; i < 10; i++) { |
| ps.setInt(1, i); |
| ps.executeUpdate(); |
| } |
| commit(); |
| } |
| |
| protected void tearDown() throws java.lang.Exception { |
| dropTable("tab1"); |
| super.tearDown(); |
| } |
| } |