| -- |
| -- 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. |
| -- |
| -- test DDL Table Lock mode |
| |
| call SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(1); |
| maximumdisplaywidth 2000; |
| CREATE PROCEDURE WAIT_FOR_POST_COMMIT() DYNAMIC RESULT SETS 0 LANGUAGE JAVA EXTERNAL NAME 'org.apache.derbyTesting.functionTests.util.T_Access.waitForPostCommitToFinish' PARAMETER STYLE JAVA; |
| |
| -- create tables with different lock modes |
| drop table default1; |
| create table default1(c1 int); |
| drop table row1; |
| create table row1(c1 int); |
| alter table row1 locksize row; |
| drop table table1; |
| create table table1(c1 int); |
| alter table table1 locksize table; |
| |
| -- verify that views have table lock mode of 'R' (ignored) |
| create view v1 as select * from table1; |
| select tablename, lockgranularity from sys.systables |
| where tablename = 'V1'; |
| drop view v1; |
| |
| -- verify that system tables have lock mode of 'R' |
| select tablename, lockgranularity from sys.systables |
| where tablename = 'SYSTABLES'; |
| |
| -- READ COMMITTED tests |
| call SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(1); |
| maximumdisplaywidth 2000; |
| |
| set current isolation = CS; |
| -- all selects should be row locked except for table1 |
| select * from default1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| select * from row1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| select * from table1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- scans for all updates should be row locked except for table1 |
| update default1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update default1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update row1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update row1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update table1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update table1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- all inserts should be row locked except for table1 |
| insert into default1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| insert into row1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| insert into table1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- scans for all deletes should be row locked except for table1 |
| delete from default1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from default1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from row1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from row1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from table1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from table1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| |
| -- REPEATABLE READ tests |
| -- repeatable read works the same as serializable when no indexes are involved |
| |
| -- create tables with different lock modes |
| drop table default1; |
| create table default1(c1 int); |
| drop table row1; |
| create table row1(c1 int); |
| alter table row1 locksize row; |
| drop table table1; |
| create table table1(c1 int); |
| alter table table1 locksize table; |
| |
| set current isolation RS; |
| -- all selects should be row locked except for table1 |
| select * from default1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| select * from row1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| select * from table1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- scans for all updates should be row locked except for table1 |
| update default1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update default1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update row1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update row1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update table1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update table1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- all inserts should be row locked except for table1 |
| insert into default1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| insert into row1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| insert into table1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- scans for all deletes should be row locked except for table1 |
| delete from default1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from default1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from row1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from row1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from table1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from table1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| |
| -- alter table |
| -- first set to same value (stupid test) |
| alter table default1 locksize row; |
| alter table row1 locksize row; |
| alter table table1 locksize table; |
| select tablename, lockGranularity from sys.systables |
| where tablename in ('DEFAULT1', 'ROW1', 'TABLE1') |
| order by tablename; |
| |
| -- set to opposite value |
| alter table default1 locksize table; |
| alter table row1 locksize table; |
| alter table table1 locksize row; |
| select tablename, lockGranularity from sys.systables |
| where tablename in ('DEFAULT1', 'ROW1', 'TABLE1') |
| order by tablename; |
| |
| -- READ UNCOMMITTED tests |
| |
| -- create tables with different lock modes |
| drop table default1; |
| create table default1(c1 int); |
| drop table row1; |
| create table row1(c1 int); |
| alter table row1 locksize row; |
| drop table table1; |
| create table table1(c1 int); |
| alter table table1 locksize table; |
| |
| set isolation = read uncommitted; |
| -- all selects should be row locked except for table1 |
| |
| select * from default1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| select * from row1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| select * from table1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- scans for all updates should be row locked except for table1 |
| update default1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update default1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update row1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update row1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update table1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update table1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- all inserts should be row locked except for table1 |
| insert into default1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| insert into row1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| insert into table1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- scans for all deletes should be row locked except for table1 |
| delete from default1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from default1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from row1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from row1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from table1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from table1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| |
| -- alter table |
| -- first set to same value (stupid test) |
| alter table default1 locksize row; |
| alter table row1 locksize row; |
| alter table table1 locksize table; |
| select tablename, lockGranularity from sys.systables |
| where tablename in ('DEFAULT1', 'ROW1', 'TABLE1') |
| order by tablename; |
| |
| -- set to opposite value |
| alter table default1 locksize table; |
| alter table row1 locksize table; |
| alter table table1 locksize row; |
| select tablename, lockGranularity from sys.systables |
| where tablename in ('DEFAULT1', 'ROW1', 'TABLE1') |
| order by tablename; |
| |
| |
| -- SERIALIZABLE tests |
| |
| -- create tables with different lock modes |
| drop table default1; |
| create table default1(c1 int); |
| drop table row1; |
| create table row1(c1 int); |
| alter table row1 locksize row; |
| drop table table1; |
| create table table1(c1 int); |
| alter table table1 locksize table; |
| |
| set isolation serializable; |
| -- all selects should be table locked since no where clause |
| select * from default1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| select * from row1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| select * from table1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- scans for all updates should be table locked |
| -- (No indexes, so will always do table scan) |
| update default1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update default1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update row1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update row1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update table1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update table1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- all inserts should be row locked except for table1 |
| insert into default1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| insert into row1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| insert into table1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- scans for all deletes should be table locked |
| -- (No indexes, so will always do table scan) |
| delete from default1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from default1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from row1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from row1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from table1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from table1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| |
| -- alter table |
| -- first set to same value (stupid test) |
| alter table default1 locksize row; |
| alter table row1 locksize row; |
| alter table table1 locksize table; |
| select tablename, lockGranularity from sys.systables |
| where tablename in ('DEFAULT1', 'ROW1', 'TABLE1') |
| order by tablename; |
| |
| -- set to opposite value |
| alter table default1 locksize table; |
| alter table row1 locksize table; |
| alter table table1 locksize row; |
| select tablename, lockGranularity from sys.systables |
| where tablename in ('DEFAULT1', 'ROW1', 'TABLE1') |
| order by tablename; |
| |
| set isolation read committed; |
| -- verify lock granularity changed for selects |
| select * from default1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| select * from row1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| select * from table1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- verify lock granularity changed for updates |
| update default1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update default1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update row1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update row1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update table1 set c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| update table1 set c1 = 1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- verify lock granularity changed for inserts |
| insert into default1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| insert into row1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| insert into table1 values 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- verify lock granularity changed for deletes |
| delete from default1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from default1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from row1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from row1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from table1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| delete from table1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| CALL WAIT_FOR_POST_COMMIT(); |
| |
| -- bug 3819; delete from table would first |
| -- end up getting an IX lock on table then |
| -- an X lock on table; this can lead to |
| -- deadlocks with multiple threads doing |
| -- delete from table. fix is to choose |
| -- row locking for deletes/updates in *all* |
| -- cases; this would result in an IX lock |
| -- on the table. means more locking but |
| -- increased concurrency. |
| insert into default1 values (1); |
| insert into default1 values (2); |
| select * from default1 order by c1; |
| |
| set isolation to CURSOR STABILITY; |
| |
| autocommit off; |
| |
| delete from default1; |
| |
| -- should see only one lock; earlier used to |
| -- see 2, one IX and one for X. |
| select count(*) |
| from syscs_diag.lock_table |
| where tablename = 'DEFAULT1' and type = 'TABLE'; |
| |
| commit; |
| |
| -- cleanup |
| drop procedure WAIT_FOR_POST_COMMIT; |
| drop table default1; |
| drop table row1; |
| drop table table1; |