ij> -- -- 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. -- -- Very basic single user testing of update row locking. run resource 'createTestProcedures.subsql'; ij> -- -- 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. -- CREATE FUNCTION PADSTRING (DATA VARCHAR(32000), LENGTH INTEGER) RETURNS VARCHAR(32000) EXTERNAL NAME 'org.apache.derbyTesting.functionTests.util.Formatters.padString' LANGUAGE JAVA PARAMETER STYLE JAVA; 0 rows inserted/updated/deleted ij> 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; 0 rows inserted/updated/deleted ij> autocommit off; ij> run resource 'LockTableQuery.subsql'; ij> -- -- 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. -- create view lock_table as select cast(username as char(8)) as username, cast(t.type as char(8)) as trantype, cast(l.type as char(8)) as type, cast(lockcount as char(3)) as cnt, mode, cast(tablename as char(12)) as tabname, cast(lockname as char(10)) as lockname, state, status from syscs_diag.lock_table l right outer join syscs_diag.transaction_table t on l.xid = t.xid where l.tableType <> 'S' and t.type='UserTransaction'; 0 rows inserted/updated/deleted ij> --on l.xid = t.xid where l.tableType <> 'S' or l.tableType is null -- order by -- tabname, type desc, mode, cnt, lockname -- lock table with system catalog locks included. create view full_lock_table as select cast(username as char(8)) as username, cast(t.type as char(8)) as trantype, cast(l.type as char(8)) as type, cast(lockcount as char(3)) as cnt, mode, cast(tablename as char(12)) as tabname, cast(lockname as char(10)) as lockname, state, status from syscs_diag.lock_table l right outer join syscs_diag.transaction_table t on l.xid = t.xid where l.tableType <> 'S' ; 0 rows inserted/updated/deleted ij> -- lock table with no join. create view lock_table2 as select cast(l.xid as char(8)) as xid, cast(l.type as char(8)) as type, cast(lockcount as char(3)) as cnt, mode, cast(tablename as char(12)) as tabname, cast(lockname as char(10)) as lockname, state from syscs_diag.lock_table l where l.tableType <> 'S' ; 0 rows inserted/updated/deleted ij> -- transaction table with no join. create view tran_table as select * from syscs_diag.transaction_table; 0 rows inserted/updated/deleted ij> commit; ij> -- READ COMMITTED TEST set isolation read committed; 0 rows inserted/updated/deleted ij> commit; ij> -- run each test with rows on one page in the interesting conglomerate (heap in -- the non-index tests, and in the index in the index based tests). -- cursor, no index run -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'updateholdcursorlocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of update locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -- Should claim a "U" lock as it visits each row. In serializable it -- will convert the lock to S when it moves off the row, having done no -- update. In read committed it will release each U lock as it moves off -- the row. -- -- Note that the current implementation claims a IX table lock when doing -- update locking, which it will not release even if no actual update is -- performed. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -- Will claim an U lock as it visits each row. Will claim an X lock on any -- row it actually deletes. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap, make sure there are no locks on the committed -- deleted rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. Will get X locks only on the rows -- which are updated. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set a=-3,b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> update a set a=-5,b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one -3 |-30 |-three -5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- -3, -30, '-three' -- -5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a < 0 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one -3 |-30 |-three -5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- -3, -30, '-three' -- -5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three -5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- -3, -30, '-three' -- -5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= -5 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three ij> update a set a=3,b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three -5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- -5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= -5 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set a=33,b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 33, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 33 |3030 |threethree ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'updateBtreeHoldCursorLocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of btree cursor update locks. This ".subsql" -- test is meant to be run from another test such that it gets run under -- multiple isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- This test concentrates on updates which use a primary index for the cursor, -- and then update a non-key field, or delete a row. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar, d somesortofpad); -- create index a_idx on (a, somesortofpad) -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, which exits in middle of scan. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> commit; ij> -- in order to get consistent locking results, wait for the post commit -- thread to finish processing the committed deleted rows. Otherwise -- the subsequent scans get timing dependent lock results dependent on -- if the background post commit gets to the deleted rows first or not. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select a from a; A ----------- 1 3 5 7 ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=-3000 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-3000 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, and bales early. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -3000, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-3000 |three ij> update a set b=30 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> update a set b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a > 0 and b < 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified exact match cursor scan which deletes one row. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a = 1 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a <> 3 and a <> 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,13) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three 5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- 3, -30, '-three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a,b,c from a where a > 2 and a <= 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three ij> update a set b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three 5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,11) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,11) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 3, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |3030 |threethree ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'updateBtreeHoldCursorLocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of btree cursor update locks. This ".subsql" -- test is meant to be run from another test such that it gets run under -- multiple isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- This test concentrates on updates which use a primary index for the cursor, -- and then update a non-key field, or delete a row. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar, d somesortofpad); -- create index a_idx on (a, somesortofpad) -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, which exits in middle of scan. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> commit; ij> -- in order to get consistent locking results, wait for the post commit -- thread to finish processing the committed deleted rows. Otherwise -- the subsequent scans get timing dependent lock results dependent on -- if the background post commit gets to the deleted rows first or not. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select a from a; A ----------- 1 3 5 7 ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=-3000 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-3000 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, and bales early. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -3000, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-3000 |three ij> update a set b=30 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> update a set b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a > 0 and b < 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified exact match cursor scan which deletes one row. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a = 1 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a <> 3 and a <> 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,13) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three 5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- 3, -30, '-three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a,b,c from a where a > 2 and a <= 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three ij> update a set b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three 5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,11) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,11) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 3, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |3030 |threethree ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- run each test with rows across multiple pages in the interesting -- conglomerate (heap in the non-index tests, and in the index in the index -- based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize', '4096'); 0 rows inserted/updated/deleted ij> create table a(a int, b int, c varchar(1900)); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900)); 1 row inserted/updated/deleted ij> commit; ij> run resource 'updateholdcursorlocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of update locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 2 |20 |two & 3 |30 |three & 4 |40 |four & 5 |50 |five & 6 |60 |six & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -- Should claim a "U" lock as it visits each row. In serializable it -- will convert the lock to S when it moves off the row, having done no -- update. In read committed it will release each U lock as it moves off -- the row. -- -- Note that the current implementation claims a IX table lock when doing -- update locking, which it will not release even if no actual update is -- performed. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -- Will claim an U lock as it visits each row. Will claim an X lock on any -- row it actually deletes. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,7) |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 3 |30 |three & 5 |50 |five & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap, make sure there are no locks on the committed -- deleted rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 3 |30 |three & 5 |50 |five & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. Will get X locks only on the rows -- which are updated. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set a=-3,b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> update a set a=-5,b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & -3 |-30 |-three -5 |-50 |-five 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- -3, -30, '-three' -- -5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a < 0 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & -3 |-30 |-three -5 |-50 |-five 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- -3, -30, '-three' -- -5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(4,6) |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three -5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- -3, -30, '-three' -- -5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= -5 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three ij> update a set a=3,b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three -5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- -5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= -5 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set a=33,b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 33, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 33 |3030 |threethree ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(600) ); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',600)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',600)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',600)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',600)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',600)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',600)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',600)); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a, index_pad); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'updateBtreeHoldCursorLocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of btree cursor update locks. This ".subsql" -- test is meant to be run from another test such that it gets run under -- multiple isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- This test concentrates on updates which use a primary index for the cursor, -- and then update a non-key field, or delete a row. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar, d somesortofpad); -- create index a_idx on (a, somesortofpad) -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, which exits in middle of scan. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> commit; ij> -- in order to get consistent locking results, wait for the post commit -- thread to finish processing the committed deleted rows. Otherwise -- the subsequent scans get timing dependent lock results dependent on -- if the background post commit gets to the deleted rows first or not. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select a from a; A ----------- 1 3 5 7 ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set b=-3000 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-3000 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, and bales early. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -3000, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-3000 |three & ij> update a set b=30 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> update a set b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a > 0 and b < 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified exact match cursor scan which deletes one row. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a = 1 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a <> 3 and a <> 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- 3, -30, '-three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a,b,c from a where a > 2 and a <= 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three ij> update a set b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three |index pad 3 & 5 |-50 |-five |index pad 5 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 3, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |3030 |threethree |index pad 3 & ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(700) ); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',700)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',700)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',700)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',700)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',700)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',700)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',700)); 1 row inserted/updated/deleted ij> create index a_idx on a (a, index_pad); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'updateBtreeHoldCursorLocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of btree cursor update locks. This ".subsql" -- test is meant to be run from another test such that it gets run under -- multiple isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- This test concentrates on updates which use a primary index for the cursor, -- and then update a non-key field, or delete a row. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar, d somesortofpad); -- create index a_idx on (a, somesortofpad) -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, which exits in middle of scan. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> commit; ij> -- in order to get consistent locking results, wait for the post commit -- thread to finish processing the committed deleted rows. Otherwise -- the subsequent scans get timing dependent lock results dependent on -- if the background post commit gets to the deleted rows first or not. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select a from a; A ----------- 1 3 5 7 ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set b=-3000 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-3000 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, and bales early. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -3000, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-3000 |three & ij> update a set b=30 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> update a set b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a > 0 and b < 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified exact match cursor scan which deletes one row. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a = 1 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a <> 3 and a <> 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- 3, -30, '-three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a,b,c from a where a > 2 and a <= 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three ij> update a set b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three |index pad 3 & 5 |-50 |-five |index pad 5 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 3, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |3030 |threethree |index pad 3 & ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> commit; ij> -- REPEATABLE READ TEST -- should be the same as SERIALIZABLE results except no previous key locks. set isolation RS; 0 rows inserted/updated/deleted ij> commit; ij> -- run each test with rows on one page in the interesting conglomerate (heap in -- the non-index tests, and in the index in the index based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize', NULL); 0 rows inserted/updated/deleted ij> create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'updateholdcursorlocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of update locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -- Should claim a "U" lock as it visits each row. In serializable it -- will convert the lock to S when it moves off the row, having done no -- update. In read committed it will release each U lock as it moves off -- the row. -- -- Note that the current implementation claims a IX table lock when doing -- update locking, which it will not release even if no actual update is -- performed. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -- Will claim an U lock as it visits each row. Will claim an X lock on any -- row it actually deletes. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap, make sure there are no locks on the committed -- deleted rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. Will get X locks only on the rows -- which are updated. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set a=-3,b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> update a set a=-5,b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one -3 |-30 |-three -5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- -3, -30, '-three' -- -5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a < 0 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one -3 |-30 |-three -5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- -3, -30, '-three' -- -5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three -5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- -3, -30, '-three' -- -5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= -5 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three ij> update a set a=3,b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three -5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- -5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= -5 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set a=33,b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 33, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 33 |3030 |threethree ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'updateBtreeHoldCursorLocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of btree cursor update locks. This ".subsql" -- test is meant to be run from another test such that it gets run under -- multiple isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- This test concentrates on updates which use a primary index for the cursor, -- and then update a non-key field, or delete a row. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar, d somesortofpad); -- create index a_idx on (a, somesortofpad) -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, which exits in middle of scan. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> commit; ij> -- in order to get consistent locking results, wait for the post commit -- thread to finish processing the committed deleted rows. Otherwise -- the subsequent scans get timing dependent lock results dependent on -- if the background post commit gets to the deleted rows first or not. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select a from a; A ----------- 1 3 5 7 ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=-3000 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-3000 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, and bales early. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -3000, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-3000 |three ij> update a set b=30 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> update a set b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a > 0 and b < 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified exact match cursor scan which deletes one row. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a = 1 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a <> 3 and a <> 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,13) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three 5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- 3, -30, '-three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a,b,c from a where a > 2 and a <= 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three ij> update a set b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three 5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,11) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,11) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 3, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |3030 |threethree ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'updateBtreeHoldCursorLocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of btree cursor update locks. This ".subsql" -- test is meant to be run from another test such that it gets run under -- multiple isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- This test concentrates on updates which use a primary index for the cursor, -- and then update a non-key field, or delete a row. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar, d somesortofpad); -- create index a_idx on (a, somesortofpad) -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, which exits in middle of scan. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,8) |GRANT|ACTIVE ij> commit; ij> -- in order to get consistent locking results, wait for the post commit -- thread to finish processing the committed deleted rows. Otherwise -- the subsequent scans get timing dependent lock results dependent on -- if the background post commit gets to the deleted rows first or not. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select a from a; A ----------- 1 3 5 7 ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=-3000 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-3000 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, and bales early. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -3000, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-3000 |three ij> update a set b=30 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> update a set b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a > 0 and b < 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified exact match cursor scan which deletes one row. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a = 1 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a <> 3 and a <> 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,13) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three 5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- 3, -30, '-three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a,b,c from a where a > 2 and a <= 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three ij> update a set b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three 5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,11) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,11) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 3, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |3030 |threethree ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- run each test with rows across multiple pages in the interesting -- conglomerate (heap in the non-index tests, and in the index in the index -- based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize', '4096'); 0 rows inserted/updated/deleted ij> create table a (a int, b int, c varchar(1900)); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900)); 1 row inserted/updated/deleted ij> commit; ij> run resource 'updateholdcursorlocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of update locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 2 |20 |two & 3 |30 |three & 4 |40 |four & 5 |50 |five & 6 |60 |six & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -- Should claim a "U" lock as it visits each row. In serializable it -- will convert the lock to S when it moves off the row, having done no -- update. In read committed it will release each U lock as it moves off -- the row. -- -- Note that the current implementation claims a IX table lock when doing -- update locking, which it will not release even if no actual update is -- performed. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -- Will claim an U lock as it visits each row. Will claim an X lock on any -- row it actually deletes. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,7) |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 3 |30 |three & 5 |50 |five & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap, make sure there are no locks on the committed -- deleted rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 3 |30 |three & 5 |50 |five & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. Will get X locks only on the rows -- which are updated. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set a=-3,b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> update a set a=-5,b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & -3 |-30 |-three -5 |-50 |-five 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- -3, -30, '-three' -- -5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a < 0 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & -3 |-30 |-three -5 |-50 |-five 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- -3, -30, '-three' -- -5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(4,6) |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three -5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- -3, -30, '-three' -- -5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= -5 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three ij> update a set a=3,b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three -5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- -5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= -5 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set a=33,b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 33, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 33 |3030 |threethree ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(600) ); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',600)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',600)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',600)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',600)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',600)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',600)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',600)); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a, index_pad); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'updateBtreeHoldCursorLocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of btree cursor update locks. This ".subsql" -- test is meant to be run from another test such that it gets run under -- multiple isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- This test concentrates on updates which use a primary index for the cursor, -- and then update a non-key field, or delete a row. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar, d somesortofpad); -- create index a_idx on (a, somesortofpad) -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, which exits in middle of scan. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> commit; ij> -- in order to get consistent locking results, wait for the post commit -- thread to finish processing the committed deleted rows. Otherwise -- the subsequent scans get timing dependent lock results dependent on -- if the background post commit gets to the deleted rows first or not. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select a from a; A ----------- 1 3 5 7 ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set b=-3000 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-3000 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, and bales early. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -3000, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-3000 |three & ij> update a set b=30 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> update a set b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a > 0 and b < 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified exact match cursor scan which deletes one row. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a = 1 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a <> 3 and a <> 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- 3, -30, '-three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a,b,c from a where a > 2 and a <= 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three ij> update a set b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three |index pad 3 & 5 |-50 |-five |index pad 5 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 3, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |3030 |threethree |index pad 3 & ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(700) ); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',700)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',700)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',700)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',700)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',700)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',700)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',700)); 1 row inserted/updated/deleted ij> create index a_idx on a (a, index_pad); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'updateBtreeHoldCursorLocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of btree cursor update locks. This ".subsql" -- test is meant to be run from another test such that it gets run under -- multiple isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- This test concentrates on updates which use a primary index for the cursor, -- and then update a non-key field, or delete a row. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar, d somesortofpad); -- create index a_idx on (a, somesortofpad) -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, which exits in middle of scan. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> commit; ij> -- in order to get consistent locking results, wait for the post commit -- thread to finish processing the committed deleted rows. Otherwise -- the subsequent scans get timing dependent lock results dependent on -- if the background post commit gets to the deleted rows first or not. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select a from a; A ----------- 1 3 5 7 ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set b=-3000 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-3000 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, and bales early. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -3000, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-3000 |three & ij> update a set b=30 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> update a set b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a > 0 and b < 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified exact match cursor scan which deletes one row. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a = 1 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a <> 3 and a <> 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- 3, -30, '-three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a,b,c from a where a > 2 and a <= 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three ij> update a set b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three |index pad 3 & 5 |-50 |-five |index pad 5 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 3, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |3030 |threethree |index pad 3 & ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> commit; ij> -- SERIALIZABLE TEST set isolation serializable; 0 rows inserted/updated/deleted ij> commit; ij> -- run each test with rows on one page in the interesting conglomerate (heap in -- the non-index tests, and in the index in the index based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize', NULL); 0 rows inserted/updated/deleted ij> create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'updateholdcursorlocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of update locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -- Should claim a "U" lock as it visits each row. In serializable it -- will convert the lock to S when it moves off the row, having done no -- update. In read committed it will release each U lock as it moves off -- the row. -- -- Note that the current implementation claims a IX table lock when doing -- update locking, which it will not release even if no actual update is -- performed. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -- Will claim an U lock as it visits each row. Will claim an X lock on any -- row it actually deletes. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap, make sure there are no locks on the committed -- deleted rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. Will get X locks only on the rows -- which are updated. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set a=-3,b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> update a set a=-5,b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one -3 |-30 |-three -5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- -3, -30, '-three' -- -5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a < 0 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one -3 |-30 |-three -5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- -3, -30, '-three' -- -5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three -5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- -3, -30, '-three' -- -5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= -5 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three ij> update a set a=3,b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three -5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- -5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= -5 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set a=33,b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 33, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 33 |3030 |threethree ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'updateBtreeHoldCursorLocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of btree cursor update locks. This ".subsql" -- test is meant to be run from another test such that it gets run under -- multiple isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- This test concentrates on updates which use a primary index for the cursor, -- and then update a non-key field, or delete a row. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar, d somesortofpad); -- create index a_idx on (a, somesortofpad) -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, which exits in middle of scan. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |6 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |6 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |6 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |6 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -- in order to get consistent locking results, wait for the post commit -- thread to finish processing the committed deleted rows. Otherwise -- the subsequent scans get timing dependent lock results dependent on -- if the background post commit gets to the deleted rows first or not. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select a from a; A ----------- 1 3 5 7 ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=-3000 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-3000 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, and bales early. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -3000, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-3000 |three ij> update a set b=30 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> update a set b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a > 0 and b < 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified exact match cursor scan which deletes one row. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a = 1 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a <> 3 and a <> 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three 5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- 3, -30, '-three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a,b,c from a where a > 2 and a <= 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three ij> update a set b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three 5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,11) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,11) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 3, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |3030 |threethree ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'updateBtreeHoldCursorLocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of btree cursor update locks. This ".subsql" -- test is meant to be run from another test such that it gets run under -- multiple isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- This test concentrates on updates which use a primary index for the cursor, -- and then update a non-key field, or delete a row. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar, d somesortofpad); -- create index a_idx on (a, somesortofpad) -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, which exits in middle of scan. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |6 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |6 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |6 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |6 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -- in order to get consistent locking results, wait for the post commit -- thread to finish processing the committed deleted rows. Otherwise -- the subsequent scans get timing dependent lock results dependent on -- if the background post commit gets to the deleted rows first or not. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select a from a; A ----------- 1 3 5 7 ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=-3000 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-3000 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, and bales early. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -3000, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-3000 |three ij> update a set b=30 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> update a set b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a > 0 and b < 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified exact match cursor scan which deletes one row. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a = 1 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three 5 |-50 |-five 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a <> 3 and a <> 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three 5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- 3, -30, '-three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a,b,c from a where a > 2 and a <= 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three ij> update a set b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three 5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,11) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,9) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,11) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 3, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |3030 |threethree ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- run each test with rows across multiple pages in the interesting -- conglomerate (heap in the non-index tests, and in the index in the index -- based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize', '4096'); 0 rows inserted/updated/deleted ij> create table a (a int, b int, c varchar(1900)); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900)); 1 row inserted/updated/deleted ij> commit; ij> run resource 'updateholdcursorlocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of update locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 2 |20 |two & 3 |30 |three & 4 |40 |four & 5 |50 |five & 6 |60 |six & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -- Should claim a "U" lock as it visits each row. In serializable it -- will convert the lock to S when it moves off the row, having done no -- update. In read committed it will release each U lock as it moves off -- the row. -- -- Note that the current implementation claims a IX table lock when doing -- update locking, which it will not release even if no actual update is -- performed. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -- Will claim an U lock as it visits each row. Will claim an X lock on any -- row it actually deletes. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 3 |30 |three & 5 |50 |five & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap, make sure there are no locks on the committed -- deleted rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 3 |30 |three & 5 |50 |five & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. Will get X locks only on the rows -- which are updated. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set a=-3,b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> update a set a=-5,b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & -3 |-30 |-three -5 |-50 |-five 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- -3, -30, '-three' -- -5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a < 0 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & -3 |-30 |-three -5 |-50 |-five 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- -3, -30, '-three' -- -5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three -5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- -3, -30, '-three' -- -5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= -5 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -3 |-30 |-three ij> update a set a=3,b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three -5 |-50 |-five ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- -5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= -5 for update'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set a=33,b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- -5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 33, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 33 |3030 |threethree ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(600) ); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',600)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',600)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',600)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',600)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',600)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',600)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',600)); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a, index_pad); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'updateBtreeHoldCursorLocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of btree cursor update locks. This ".subsql" -- test is meant to be run from another test such that it gets run under -- multiple isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- This test concentrates on updates which use a primary index for the cursor, -- and then update a non-key field, or delete a row. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar, d somesortofpad); -- create index a_idx on (a, somesortofpad) -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, which exits in middle of scan. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> commit; ij> -- in order to get consistent locking results, wait for the post commit -- thread to finish processing the committed deleted rows. Otherwise -- the subsequent scans get timing dependent lock results dependent on -- if the background post commit gets to the deleted rows first or not. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select a from a; A ----------- 1 3 5 7 ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set b=-3000 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-3000 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, and bales early. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -3000, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-3000 |three & ij> update a set b=30 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> update a set b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a > 0 and b < 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified exact match cursor scan which deletes one row. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a = 1 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a <> 3 and a <> 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- 3, -30, '-three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a,b,c from a where a > 2 and a <= 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three ij> update a set b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three |index pad 3 & 5 |-50 |-five |index pad 5 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 3, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |3030 |threethree |index pad 3 & ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(700) ); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',700)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',700)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',700)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',700)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',700)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',700)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',700)); 1 row inserted/updated/deleted ij> create index a_idx on a (a, index_pad); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'updateBtreeHoldCursorLocksJDBC30.subsql'; ij> -- -- 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. -- -- Very basic single user testing of btree cursor update locks. This ".subsql" -- test is meant to be run from another test such that it gets run under -- multiple isolation levels. This is important for update locks as they behave -- differently, depending on isolation levels. -- -- This test concentrates on updates which use a primary index for the cursor, -- and then update a non-key field, or delete a row. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar, d somesortofpad); -- create index a_idx on (a, somesortofpad) -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, which exits in middle of scan. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which deletes "even" rows. -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |5 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |7 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(6,6) |GRANT|ACTIVE ij> commit; ij> -- in order to get consistent locking results, wait for the post commit -- thread to finish processing the committed deleted rows. Otherwise -- the subsequent scans get timing dependent lock results dependent on -- if the background post commit gets to the deleted rows first or not. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select a from a; A ----------- 1 3 5 7 ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which does no updates, now there are committed -- deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set b=-3000 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-3000 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test exact match cursor scan does one update, and bales early. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -3000, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a = 3 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-3000 |three & ij> update a set b=30 where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |30 |three &|index pad 3 & 5 |50 |five &|index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test full cursor scan which updates the middle 2 rows, now there are -- committed deleted rows in the heap. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a >= 1 and a < 20 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> update a set b=-30,c='-three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> update a set b=-50,c='-five' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which does no updates. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a > 0 and b < 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified exact match cursor scan which deletes one row. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a = 1 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |3 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which deletes the positive rows. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, -30, '-three' -- 5, -50, '-five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a from a where a <> 3 and a <> 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|TABLE |1 |X |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three |index pad 3 & 5 |-50 |-five |index pad 5 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row. -- -- At this point the table should look like: -- 3, -30, '-three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a,b,c from a where a > 2 and a <= 5 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |-30 |-three ij> update a set b=30,c='three' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three |index pad 3 & 5 |-50 |-five |index pad 5 & ij> commit; ij> -------------------------------------------------------------------------------- -- Test qualified full cursor scan which updates a row and deletes a row. -- -- At this point the table should look like: -- 3, 30, 'three' -- 5, -50, '-five' -------------------------------------------------------------------------------- get with hold cursor scan_cursor as 'select a, b, c from a where a > 0 for update of b, c'; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IX |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> update a set b=3030,c='threethree' where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |2 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |-50 |-five ij> delete from a where current of scan_cursor; 1 row inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |4 |IX |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |U |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |X |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |2 |X |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> ------------------------------------------------------------------------------- -- At this point the table should look like: -- 3, 3030, 'threethree' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |3030 |threethree |index pad 3 & ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> commit; ij> exit;