Monday, December 11, 2023



Oracle Database 23c–Fine Grained Locking–Lock Free Reservations:

Session 1 inserts a record and commits it. Session 1 performs an update on this record. And does not yet commit its transaction. Session 2 tries to update that same record …. and is able to! It does not run into a lock. It can perform the update, almost as if session 1 does not exist.

The traditional behavior of the Oracle Database is to lock a row as soon as it is updated. Some databases lock a table or a page (set of records) but from its incarnation, Oracle Database has always been very fine grained by only locking the row in question. However, this example shows that in release 23c it can lock even less than a single record. It does lock – make no mistake

When I invoked a third session and perform two more updates, you will see that the these transactions are not isolated from each other. It is not wild west, free for all. There are still rules enforced.

Step 4 in session B selects the current capacity and finds that the value in column capacity is still at the original 2000 despite the update in session B just prior to this query that took 800 from that capacity.

Step 5 in session C reduces the capacity by another 400 – although a query for the current capacity in that session would also return the original 2000. This update is accepted – again while both sessions A and B have made their own claims on that ticket capacity. Still no row lock preventing session C from making the update. However in step 6, when session C tries to get hold of another 700 (tickets), we finally run into a limitation: a Check Constraint violation. Not shown yet: there is a Check Constraint defined against table ticketsales that prevents the value of capacity from getting below 10.

Despite the fact that the value of column capacity for this record is still at 2000, there are claims (“reservations”) from session A (200), session B (300) and session C (400) that have virtually drained 900 from that original 2000, meaning that the 600 that was attempted to take out in step 7 were no longer available.

Let’s now commit session A (step 8) – definitively getting hold of the 200- , rollback session B (step 9) – releasing the claim of 300 – and trying to claim those 600 tickets again in session C (step 10).

What we have seen in action here is Lock-Free Reservations. A feature that allows us to have the Oracle Database manage pools of resources – tickets, seats, account balance, lottery tickets – without locking database records. To have multiple transactions each take out a claim on a slice of the resource pool, they do not have to lock the record that describes that particular pool – thereby excluding other transactions until the transaction is either committed or rolled back. They can instead create a reservation, that guarantees that the slice they requested is available by the time they commit. Oracle Database makes sure that not more reservations can be created than the pool can sustain. Many transactions can hold reservations on the same pool [record] at the same time: they do not interfere. The allows for a much higher degree of concurrency than is possible with table, page or even record locking.

Working with a resource pool with lock-free reservations is quite straightforward:

define a column as reservable. This must be a numeric column define check constraint(s) to control the allowable values for the column (usually limiting the lower or upper capacity limit; note: check constraints can compare non reservable (regular) columns with reservable columns access the record to be updated using its primary / unique key – make sure the update is a single row statement do not use for update of when updating the reservable column’s value (as that would defeat the purpose) only use set column = column + claim or set column = column – claim to claim part of the capacity; do not use set column = value the pool can be replenished; capacity can be added for example. However, the transaction that adds capacity needs to be committed before it will have an effect on additional reservations that can be made by other transactions.

Oracle Database creates a “Reservation Journal Table” – SYS_RESERVJRNL_<object_number_of_base_table> – that records the claims made against a resource pool. This table behaves like a global temporary table: each session only sees its own claims. When the session commits (or rolls back) the table is cleared. Flashback query does not return values from this table and even SYS cannot look across sessions to find all currently held reservations

In very brief the definition of the table used in this example:

SQL> CREATE TABLE TICKETSALES(ID NUMBER PRIMARY KEY, NAME VARCHAR2(100),CAPACITY NUMBER RESERVABLE CONSTRAINT MINIMUM_CAPACITY CHECK (CAPACITY >= 10));

Column CAPACITY is defined as reservable and it appear in the check constraint minimum_capacity that enforces the rule that the capacity should never be lower than 10.

The Reservation Journal Table created in this case:

(where 78947 is the OBJECT_ID found for table TICKETSALES in a query against USER_OBJECTS WHERE OBJECT_NAME=’TICKETSALES’).

Here is an example of the information available to the current transaction regarding its reservations:

SQL> UPDATE DEMO.TICKETSALES SET CAPACITY=CAPACITY - 300 WHERE ID=1;

SQL> SELECT * FROM SYS_RESERVJRNL_OBJ_ID;

SQL> UPDATE DEMO.TICKETSALES SET CAPACITY=CAPACITY - 150 WHERE ID=1;

SQL> SELECT * FROM SYS_RESERVJRNL_OBJ_ID;

SQL> SELECT * FROM TICKETSALES;

These Lock-Free Reservations are among the most intriguing application development oriented features in the latest Oracle Database release. Transactions vying for the resources from the same collection – without heavy handedly locking each other out on a record lock. It seems quite elegant and useful. There is of course much more to be looked into. (When) do row level triggers fire for example. Can we define triggers on the journal table – and would that ever make sense? How can we find out what the maximum claim is a transaction can make? Just trying until we hit a limit? Can we intercept ‘release of a claim’ or ‘replenishment of a resource’?

DEMONSTRATION STEPS:

SQL> create user demo identified by demo12345;

User created.

SQL> grant connect, create session to demo;

Grant succeeded.

SQL> alter user demo default tablespace users;

User altered.

SQL> alter user demo temporary tablespace temp;

User altered.

SQL> grant sysdba, dba to demo;

Grant succeeded.

SQL> create user test1 identified by test12345;

User created.

SQL> grant connect, create session to test1;

Grant succeeded.

SQL> grant select, insert, update, delete on DEMO.TICKETSALES to test1;

Grant succeeded.

SQL> create user test2 identified by test12345;

User created.

SQL> grant connect, create session to test2;

Grant succeeded.

SQL> grant select, insert, update, delete on DEMO.TICKETSALES to test2;

Grant succeeded.

SQL> create user test3 identified by test12345;

User created.

SQL> grant connect, create session to test3;

Grant succeeded.

SQL> grant select, insert, update, delete on DEMO.TICKETSALES to test3;

Grant succeeded.

SQL> col username for a10

SQL> col account_status for a10

SQL> select username,account_status from dba_users where username in ('TEST1','TEST2','TEST3');

USERNAME   ACCOUNT_ST

---------- ----------

TEST1      OPEN

TEST2      OPEN

TEST3      OPEN

SQL> grant update any table to TEST1,TEST2,TEST3;

Grant succeeded.

SQL> grant select any table to TEST1,TEST2,TEST3;

Grant succeeded.

SQL> grant select, insert, update, delete on "DEMO"."SYS_RESERVJRNL_78959" to TEST1,TEST2,TEST3;

Grant succeeded.

SESSION - A:

STEP1:

SQL> INSERT INTO DEMO.TICKETSALES VALUES (1, 'Instagram Live', 2000);

STEP2:

SQL> COMMIT;

STEP3:

SQL> UPDATE DEMO.TICKETSALES SET CAPACITY=CAPACITY - 200 WHERE ID=1;

STEP8:

SQL> COMMIT;

SQL> SELECT CAPACITY FROM DEMO.TICKETSALES WHERE ID=1;

SESSION - B:

STEP4:

SQL> UPDATE DEMO.TICKETSALES SET CAPACITY=CAPACITY - 800 WHERE ID=1;

STEP5:

SQL> SELECT CAPACITY FROM DEMO.TICKETSALES WHERE ID=1;

STEP9:

SQL> ROLLBACK;

SQL> SELECT CAPACITY FROM DEMO.TICKETSALES WHERE ID=1;

SESSION - C:

STEP6:

SQL> UPDATE DEMO.TICKETSALES SET CAPACITY=CAPACITY - 500 WHERE ID=1;

STEP7:

SQL> UPDATE DEMO.TICKETSALES SET CAPACITY=CAPACITY - 700 WHERE ID=1;

STEP10:

SQL> UPDATE DEMO.TICKETSALES SET CAPACITY=CAPACITY - 700 WHERE ID=1;

Main Session Log:

login as: oracle

oracle@192.168.56.5's password:

Web console: https://srlab.localdomain:9090/

Last login: Sat Nov 11 12:24:09 2023 from 192.168.56.1

[oracle@srlab ~]$ ps -ef |grep pmon

oracle      4632       1  0 10:37 ?        00:00:06 db_pmon_FREE

oracle     25930   25638  0 17:12 pts/1    00:00:00 grep --color=auto pmon

[oracle@srlab ~]$ ps -ef |grep tns

root          21       2  0 10:36 ?        00:00:00 [netns]

oracle      2153       1  0 10:37 ?        00:00:01 /opt/oracle/product/23c/dbhomeFree/bin/tnslsnr LISTENER -inherit

oracle     25942   25638  0 17:12 pts/1    00:00:00 grep --color=auto tns

[oracle@srlab ~]$

[oracle@srlab ~]$ . oraenv

ORACLE_SID = [oracle] ? FREE

The Oracle base has been set to /opt/oracle

[oracle@srlab ~]$

[oracle@srlab ~]$ sqlplus / as sysdba

SQL*Plus: Release 23.0.0.0.0 - Developer-Release on Sat Nov 11 17:13:32 2023

Version 23.2.0.0.0

Copyright (c) 1982, 2023, Oracle.  All rights reserved.

Connected to:

Oracle Database 23c Free, Release 23.0.0.0.0 - Developer-Release

Version 23.2.0.0.0

SQL> select * from global_name;

GLOBAL_NAME

--------------------------

SRLAB23C

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED

---------- ------------------------------ ---------- ----------

         2 PDB$SEED                       READ ONLY  NO

         3 SRLABPLUG                      READ WRITE NO

SQL> alter session set container=SRLABPLUG;

Session altered.

SQL>

SQL> set lines 300 pages 2000

SQL>

SQL> create user demo identified by demo12345 default tablespace users temporary tablespace temp;

User created.

SQL> grant connect, create sessions, sysdba, dba to demo;

grant connect, create sessions, sysdba, dba to demo

               *

ERROR at line 1:

ORA-00990: missing or invalid privilege

SQL> grant connect, create session, sysdba, dba to demo;

Grant succeeded.

SQL>

SQL> col username for a10

SQL> col account_status for a10

SQL>

SQL> select username,account_status from dba_users where username='DEMO';

USERNAME   ACCOUNT_ST

---------- ----------

DEMO       OPEN

SQL> exit

Disconnected from Oracle Database 23c Free, Release 23.0.0.0.0 - Developer-Release

Version 23.2.0.0.0

[oracle@srlab ~]$ sqlplus demo@srlabplug

SQL*Plus: Release 23.0.0.0.0 - Developer-Release on Sat Nov 11 17:17:01 2023

Version 23.2.0.0.0

Copyright (c) 1982, 2023, Oracle.  All rights reserved.

Enter password:

Connected to:

Oracle Database 23c Free, Release 23.0.0.0.0 - Developer-Release

Version 23.2.0.0.0

SQL>

SQL> select * from global_name;

GLOBAL_NAME

-----------------------------------------------

SRLABPLUG

SQL> sho user

USER is "DEMO"

SQL>

SQL> create table ticketsales(id number primary key, name varchar2(100), capacity number reservable constraint minimum_capacity check (capacity>=10));

Table created.

SQL> col owner for a10

SQL> col object_name for a15

SQL> select owner,object_name,object_type,last_ddl_time,status from dba_objects where owner='DEMO';

OWNER      OBJECT_NAME     OBJECT_TYPE             LAST_DDL_ STATUS

---------- --------------- ----------------------- --------- -------

DEMO       TICKETSALES     TABLE                   11-NOV-23 VALID

DEMO       SYS_RESERVJRNL_ TABLE                   11-NOV-23 VALID

           78965

DEMO       SYS_C008232     INDEX                   11-NOV-23 VALID

SQL> col object_name for a40

SQL> /

OWNER      OBJECT_NAME                              OBJECT_TYPE

---------- ---------------------------------------- -----------------------

LAST_DDL_ STATUS

--------- -------

DEMO       TICKETSALES                              TABLE

11-NOV-23 VALID

DEMO       SYS_RESERVJRNL_78965                     TABLE

11-NOV-23 VALID

DEMO       SYS_C008232                              INDEX

11-NOV-23 VALID

SQL> set lines 300 pages 200

SQL> /

OWNER      OBJECT_NAME                              OBJECT_TYPE             LAST_DDL_ STATUS

---------- ---------------------------------------- ----------------------- --------- -------

DEMO       TICKETSALES                              TABLE                   11-NOV-23 VALID

DEMO       SYS_RESERVJRNL_78965                     TABLE                   11-NOV-23 VALID

DEMO       SYS_C008232                              INDEX                   11-NOV-23 VALID

SQL> set lines 100

SQL> desc DEMO.TICKETSALES

 Name                                                  Null?    Type

 ----------------------------------------------------- -------- ------------------------------------

 ID                                                    NOT NULL NUMBER

 NAME                                                           VARCHAR2(100)

 CAPACITY                                              NOT NULL NUMBER


SQL> select owner,object_type,status,count(*) from dba_objects where owner='DEMO' group by owner,object_type,status;

OWNER      OBJECT_TYPE             STATUS    COUNT(*)

---------- ----------------------- ------- ----------

DEMO       TABLE                   VALID            2

DEMO       INDEX                   VALID            1

SQL>

SQL> conn / as sysdba

Connected.

SQL>

SQL> sho pdbs


    CON_ID CON_NAME                       OPEN MODE  RESTRICTED

---------- ------------------------------ ---------- ----------

         2 PDB$SEED                       READ ONLY  NO

         3 SRLABPLUG                      READ WRITE NO

SQL>

SQL> alter session set container=SRLABPLUG;

Session altered.

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED

---------- ------------------------------ ---------- ----------

         3 SRLABPLUG                      READ WRITE NO

SQL>

SQL> create user test1 identified by test12345;

create user test1 identified by test12345

            *

ERROR at line 1:

ORA-01920: user name 'TEST1' conflicts with another user or role name

SQL> drop user test1 cascade;

User dropped.

SQL> drop user test2 cascade;

User dropped.

SQL> drop user test3 cascade;

User dropped.

SQL> create user test1 identified by test12345;

User created.

SQL> create user test2 identified by test12345;

User created.

SQL> create user test3 identified by test12345;

User created.

SQL> grant connect, create session to test1, test2, test3;

Grant succeeded.

SQL> grant select,insert,update,delete on demo.ticketsales to test1,test2,test3;

Grant succeeded.

SQL> grant select,insert,update,delete on demo.SYS_RESERVJRNL_78965 to test1,test2,test3;

Grant succeeded.

SQL> col username for a10

SQL> col acount_status for a10

SQL>

SQL> select username,account_status from dba_users where username in ('TEST1','TEST2','TEST3');

USERNAME   ACCOUNT_STATUS

---------- --------------------------------

TEST1      OPEN

TEST2      OPEN

TEST3      OPEN

SQL> col grantee for a10

SQL> col grantor for a10

SQL> col privilege for a10

SQL> col owner for a10

SQL> col table_name for a40

SQL> select * from dba_tab_privs where grantee in ('TEST1','TEST2','TEST3');

GRANTEE    OWNER      TABLE_NAME                               GRANTOR    PRIVILEGE  GRA HIE COM

---------- ---------- ---------------------------------------- ---------- ---------- --- --- ---

TYPE                     INH

------------------------ ---

TEST1      DEMO       TICKETSALES                              DEMO       DELETE     NO  NO  NO

TABLE                    NO

TEST1      DEMO       SYS_RESERVJRNL_78965                     DEMO       DELETE     NO  NO  NO

TABLE                    NO

TEST2      DEMO       TICKETSALES                              DEMO       DELETE     NO  NO  NO

TABLE                    NO

TEST2      DEMO       SYS_RESERVJRNL_78965                     DEMO       DELETE     NO  NO  NO

TABLE                    NO

TEST3      DEMO       TICKETSALES                              DEMO       DELETE     NO  NO  NO

TABLE                    NO

TEST3      DEMO       SYS_RESERVJRNL_78965                     DEMO       DELETE     NO  NO  NO

TABLE                    NO

TEST1      DEMO       TICKETSALES                              DEMO       INSERT     NO  NO  NO

TABLE                    NO

TEST1      DEMO       SYS_RESERVJRNL_78965                     DEMO       INSERT     NO  NO  NO

TABLE                    NO

TEST2      DEMO       TICKETSALES                              DEMO       INSERT     NO  NO  NO

TABLE                    NO

TEST2      DEMO       SYS_RESERVJRNL_78965                     DEMO       INSERT     NO  NO  NO

TABLE                    NO

TEST3      DEMO       TICKETSALES                              DEMO       INSERT     NO  NO  NO

TABLE                    NO

TEST3      DEMO       SYS_RESERVJRNL_78965                     DEMO       INSERT     NO  NO  NO

TABLE                    NO

TEST1      DEMO       TICKETSALES                              DEMO       SELECT     NO  NO  NO

TABLE                    NO

TEST1      DEMO       SYS_RESERVJRNL_78965                     DEMO       SELECT     NO  NO  NO

TABLE                    NO

TEST2      DEMO       TICKETSALES                              DEMO       SELECT     NO  NO  NO

TABLE                    NO

TEST2      DEMO       SYS_RESERVJRNL_78965                     DEMO       SELECT     NO  NO  NO

TABLE                    NO

TEST3      DEMO       TICKETSALES                              DEMO       SELECT     NO  NO  NO

TABLE                    NO

TEST3      DEMO       SYS_RESERVJRNL_78965                     DEMO       SELECT     NO  NO  NO

TABLE                    NO

TEST1      DEMO       TICKETSALES                              DEMO       UPDATE     NO  NO  NO

TABLE                    NO

TEST1      DEMO       SYS_RESERVJRNL_78965                     DEMO       UPDATE     NO  NO  NO

TABLE                    NO

TEST2      DEMO       TICKETSALES                              DEMO       UPDATE     NO  NO  NO

TABLE                    NO

TEST2      DEMO       SYS_RESERVJRNL_78965                     DEMO       UPDATE     NO  NO  NO

TABLE                    NO

TEST3      DEMO       TICKETSALES                              DEMO       UPDATE     NO  NO  NO

TABLE                    NO

TEST3      DEMO       SYS_RESERVJRNL_78965                     DEMO       UPDATE     NO  NO  NO

TABLE                    NO

24 rows selected.

SQL> col tabel_name for a30

SQL> /

GRANTEE    OWNER      TABLE_NAME                               GRANTOR    PRIVILEGE  GRA HIE COM

---------- ---------- ---------------------------------------- ---------- ---------- --- --- ---

TYPE                     INH

------------------------ ---

TEST1      DEMO       TICKETSALES                              DEMO       DELETE     NO  NO  NO

TABLE                    NO

TEST1      DEMO       SYS_RESERVJRNL_78965                     DEMO       DELETE     NO  NO  NO

TABLE                    NO

TEST2      DEMO       TICKETSALES                              DEMO       DELETE     NO  NO  NO

TABLE                    NO

TEST2      DEMO       SYS_RESERVJRNL_78965                     DEMO       DELETE     NO  NO  NO

TABLE                    NO

TEST3      DEMO       TICKETSALES                              DEMO       DELETE     NO  NO  NO

TABLE                    NO

TEST3      DEMO       SYS_RESERVJRNL_78965                     DEMO       DELETE     NO  NO  NO

TABLE                    NO

TEST1      DEMO       TICKETSALES                              DEMO       INSERT     NO  NO  NO

TABLE                    NO

TEST1      DEMO       SYS_RESERVJRNL_78965                     DEMO       INSERT     NO  NO  NO

TABLE                    NO

TEST2      DEMO       TICKETSALES                              DEMO       INSERT     NO  NO  NO

TABLE                    NO

TEST2      DEMO       SYS_RESERVJRNL_78965                     DEMO       INSERT     NO  NO  NO

TABLE                    NO

TEST3      DEMO       TICKETSALES                              DEMO       INSERT     NO  NO  NO

TABLE                    NO

TEST3      DEMO       SYS_RESERVJRNL_78965                     DEMO       INSERT     NO  NO  NO

TABLE                    NO

TEST1      DEMO       TICKETSALES                              DEMO       SELECT     NO  NO  NO

TABLE                    NO

TEST1      DEMO       SYS_RESERVJRNL_78965                     DEMO       SELECT     NO  NO  NO

TABLE                    NO

TEST2      DEMO       TICKETSALES                              DEMO       SELECT     NO  NO  NO

TABLE                    NO

TEST2      DEMO       SYS_RESERVJRNL_78965                     DEMO       SELECT     NO  NO  NO

TABLE                    NO

TEST3      DEMO       TICKETSALES                              DEMO       SELECT     NO  NO  NO

TABLE                    NO

TEST3      DEMO       SYS_RESERVJRNL_78965                     DEMO       SELECT     NO  NO  NO

TABLE                    NO

TEST1      DEMO       TICKETSALES                              DEMO       UPDATE     NO  NO  NO

TABLE                    NO

TEST1      DEMO       SYS_RESERVJRNL_78965                     DEMO       UPDATE     NO  NO  NO

TABLE                    NO

TEST2      DEMO       TICKETSALES                              DEMO       UPDATE     NO  NO  NO

TABLE                    NO

TEST2      DEMO       SYS_RESERVJRNL_78965                     DEMO       UPDATE     NO  NO  NO

TABLE                    NO

TEST3      DEMO       TICKETSALES                              DEMO       UPDATE     NO  NO  NO

TABLE                    NO

TEST3      DEMO       SYS_RESERVJRNL_78965                     DEMO       UPDATE     NO  NO  NO

TABLE                    NO

24 rows selected.


SQL> set lines 300 pages 200

SQL> /

GRANTEE    OWNER      TABLE_NAME                               GRANTOR    PRIVILEGE  GRA HIE COM TYPE   INH

---------- ---------- ---------------------------------------- ---------- ---------- --- --- --- ------------------------ ---

TEST1      DEMO       TICKETSALES                              DEMO       DELETE     NO  NO  NO  TABLE  NO

TEST1      DEMO       SYS_RESERVJRNL_78965                     DEMO       DELETE     NO  NO  NO  TABLE  NO

TEST2      DEMO       TICKETSALES                              DEMO       DELETE     NO  NO  NO  TABLE  NO

TEST2      DEMO       SYS_RESERVJRNL_78965                     DEMO       DELETE     NO  NO  NO  TABLE  NO

TEST3      DEMO       TICKETSALES                              DEMO       DELETE     NO  NO  NO  TABLE  NO

TEST3      DEMO       SYS_RESERVJRNL_78965                     DEMO       DELETE     NO  NO  NO  TABLE  NO

TEST1      DEMO       TICKETSALES                              DEMO       INSERT     NO  NO  NO  TABLE  NO

TEST1      DEMO       SYS_RESERVJRNL_78965                     DEMO       INSERT     NO  NO  NO  TABLE  NO

TEST2      DEMO       TICKETSALES                              DEMO       INSERT     NO  NO  NO  TABLE  NO

TEST2      DEMO       SYS_RESERVJRNL_78965                     DEMO       INSERT     NO  NO  NO  TABLE  NO

TEST3      DEMO       TICKETSALES                              DEMO       INSERT     NO  NO  NO  TABLE  NO

TEST3      DEMO       SYS_RESERVJRNL_78965                     DEMO       INSERT     NO  NO  NO  TABLE  NO

TEST1      DEMO       TICKETSALES                              DEMO       SELECT     NO  NO  NO  TABLE  NO

TEST1      DEMO       SYS_RESERVJRNL_78965                     DEMO       SELECT     NO  NO  NO  TABLE  NO

TEST2      DEMO       TICKETSALES                              DEMO       SELECT     NO  NO  NO  TABLE  NO

TEST2      DEMO       SYS_RESERVJRNL_78965                     DEMO       SELECT     NO  NO  NO  TABLE  NO

TEST3      DEMO       TICKETSALES                              DEMO       SELECT     NO  NO  NO  TABLE  NO

TEST3      DEMO       SYS_RESERVJRNL_78965                     DEMO       SELECT     NO  NO  NO  TABLE  NO

TEST1      DEMO       TICKETSALES                              DEMO       UPDATE     NO  NO  NO  TABLE  NO

TEST1      DEMO       SYS_RESERVJRNL_78965                     DEMO       UPDATE     NO  NO  NO  TABLE  NO

TEST2      DEMO       TICKETSALES                              DEMO       UPDATE     NO  NO  NO  TABLE  NO

TEST2      DEMO       SYS_RESERVJRNL_78965                     DEMO       UPDATE     NO  NO  NO  TABLE  NO

TEST3      DEMO       TICKETSALES                              DEMO       UPDATE     NO  NO  NO  TABLE  NO

TEST3      DEMO       SYS_RESERVJRNL_78965                     DEMO       UPDATE     NO  NO  NO  TABLE  NO

24 rows selected.

SQL> col TABLE_NAME for a20

SQL> /

GRANTEE    OWNER      TABLE_NAME           GRANTOR    PRIVILEGE  GRA HIE COM TYPE                     INH

---------- ---------- -------------------- ---------- ---------- --- --- --- ------------------------ ---

TEST1      DEMO       TICKETSALES          DEMO       DELETE     NO  NO  NO  TABLE                    NO

TEST1      DEMO       SYS_RESERVJRNL_78965 DEMO       DELETE     NO  NO  NO  TABLE                    NO

TEST2      DEMO       TICKETSALES          DEMO       DELETE     NO  NO  NO  TABLE                    NO

TEST2      DEMO       SYS_RESERVJRNL_78965 DEMO       DELETE     NO  NO  NO  TABLE                    NO

TEST3      DEMO       TICKETSALES          DEMO       DELETE     NO  NO  NO  TABLE                    NO

TEST3      DEMO       SYS_RESERVJRNL_78965 DEMO       DELETE     NO  NO  NO  TABLE                    NO

TEST1      DEMO       TICKETSALES          DEMO       INSERT     NO  NO  NO  TABLE                    NO

TEST1      DEMO       SYS_RESERVJRNL_78965 DEMO       INSERT     NO  NO  NO  TABLE                    NO

TEST2      DEMO       TICKETSALES          DEMO       INSERT     NO  NO  NO  TABLE                    NO

TEST2      DEMO       SYS_RESERVJRNL_78965 DEMO       INSERT     NO  NO  NO  TABLE                    NO

TEST3      DEMO       TICKETSALES          DEMO       INSERT     NO  NO  NO  TABLE                    NO

TEST3      DEMO       SYS_RESERVJRNL_78965 DEMO       INSERT     NO  NO  NO  TABLE                    NO

TEST1      DEMO       TICKETSALES          DEMO       SELECT     NO  NO  NO  TABLE                    NO

TEST1      DEMO       SYS_RESERVJRNL_78965 DEMO       SELECT     NO  NO  NO  TABLE                    NO

TEST2      DEMO       TICKETSALES          DEMO       SELECT     NO  NO  NO  TABLE                    NO

TEST2      DEMO       SYS_RESERVJRNL_78965 DEMO       SELECT     NO  NO  NO  TABLE                    NO

TEST3      DEMO       TICKETSALES          DEMO       SELECT     NO  NO  NO  TABLE                    NO

TEST3      DEMO       SYS_RESERVJRNL_78965 DEMO       SELECT     NO  NO  NO  TABLE                    NO

TEST1      DEMO       TICKETSALES          DEMO       UPDATE     NO  NO  NO  TABLE                    NO

TEST1      DEMO       SYS_RESERVJRNL_78965 DEMO       UPDATE     NO  NO  NO  TABLE                    NO

TEST2      DEMO       TICKETSALES          DEMO       UPDATE     NO  NO  NO  TABLE                    NO

TEST2      DEMO       SYS_RESERVJRNL_78965 DEMO       UPDATE     NO  NO  NO  TABLE                    NO

TEST3      DEMO       TICKETSALES          DEMO       UPDATE     NO  NO  NO  TABLE                    NO

TEST3      DEMO       SYS_RESERVJRNL_78965 DEMO       UPDATE     NO  NO  NO  TABLE                    NO

24 rows selected.

SQL> col TYPE for a10

SQL> /

GRANTEE    OWNER      TABLE_NAME           GRANTOR    PRIVILEGE  GRA HIE COM TYPE       INH

---------- ---------- -------------------- ---------- ---------- --- --- --- ---------- ---

TEST1      DEMO       TICKETSALES          DEMO       DELETE     NO  NO  NO  TABLE      NO

TEST1      DEMO       SYS_RESERVJRNL_78965 DEMO       DELETE     NO  NO  NO  TABLE      NO

TEST2      DEMO       TICKETSALES          DEMO       DELETE     NO  NO  NO  TABLE      NO

TEST2      DEMO       SYS_RESERVJRNL_78965 DEMO       DELETE     NO  NO  NO  TABLE      NO

TEST3      DEMO       TICKETSALES          DEMO       DELETE     NO  NO  NO  TABLE      NO

TEST3      DEMO       SYS_RESERVJRNL_78965 DEMO       DELETE     NO  NO  NO  TABLE      NO

TEST1      DEMO       TICKETSALES          DEMO       INSERT     NO  NO  NO  TABLE      NO

TEST1      DEMO       SYS_RESERVJRNL_78965 DEMO       INSERT     NO  NO  NO  TABLE      NO

TEST2      DEMO       TICKETSALES          DEMO       INSERT     NO  NO  NO  TABLE      NO

TEST2      DEMO       SYS_RESERVJRNL_78965 DEMO       INSERT     NO  NO  NO  TABLE      NO

TEST3      DEMO       TICKETSALES          DEMO       INSERT     NO  NO  NO  TABLE      NO

TEST3      DEMO       SYS_RESERVJRNL_78965 DEMO       INSERT     NO  NO  NO  TABLE      NO

TEST1      DEMO       TICKETSALES          DEMO       SELECT     NO  NO  NO  TABLE      NO

TEST1      DEMO       SYS_RESERVJRNL_78965 DEMO       SELECT     NO  NO  NO  TABLE      NO

TEST2      DEMO       TICKETSALES          DEMO       SELECT     NO  NO  NO  TABLE      NO

TEST2      DEMO       SYS_RESERVJRNL_78965 DEMO       SELECT     NO  NO  NO  TABLE      NO

TEST3      DEMO       TICKETSALES          DEMO       SELECT     NO  NO  NO  TABLE      NO

TEST3      DEMO       SYS_RESERVJRNL_78965 DEMO       SELECT     NO  NO  NO  TABLE      NO

TEST1      DEMO       TICKETSALES          DEMO       UPDATE     NO  NO  NO  TABLE      NO

TEST1      DEMO       SYS_RESERVJRNL_78965 DEMO       UPDATE     NO  NO  NO  TABLE      NO

TEST2      DEMO       TICKETSALES          DEMO       UPDATE     NO  NO  NO  TABLE      NO

TEST2      DEMO       SYS_RESERVJRNL_78965 DEMO       UPDATE     NO  NO  NO  TABLE      NO

TEST3      DEMO       TICKETSALES          DEMO       UPDATE     NO  NO  NO  TABLE      NO

TEST3      DEMO       SYS_RESERVJRNL_78965 DEMO       UPDATE     NO  NO  NO  TABLE      NO

24 rows selected.

SQL> l

  1* select * from dba_tab_privs where grantee in ('TEST1','TEST2','TEST3')

SQL> select * from demo.SYS_RESERVJRNL_78965;

no rows selected

SQL>

Test1 session log:

login as: oracle

oracle@192.168.56.5's password:

Web console: https://srlab.localdomain:9090/

Last login: Sat Nov 11 17:02:44 2023 from 192.168.56.1

[oracle@srlab ~]$

[oracle@srlab ~]$

[oracle@srlab ~]$ . oraenv

ORACLE_SID = [oracle] ? FREE

The Oracle base has been set to /opt/oracle

[oracle@srlab ~]$

[oracle@srlab ~]$ sqlplus test1@srlabplug

SQL*Plus: Release 23.0.0.0.0 - Developer-Release on Sat Nov 11 17:30:12 2023

Version 23.2.0.0.0

Copyright (c) 1982, 2023, Oracle.  All rights reserved.

Enter password:

Connected to:

Oracle Database 23c Free, Release 23.0.0.0.0 - Developer-Release

Version 23.2.0.0.0

SQL> show user

USER is "TEST1"

SQL> select * from global_name;

GLOBAL_NAME

--------------------------------------------------------------------

SRLABPLUG

SQL> insert into demo.ticketsales values (1, 'ARR Concert', 2000);

1 row created.

SQL> commit;

Commit complete.

SQL> update demo.ticketsales set capacity=capacity - 200 where id=1;

1 row updated.

SQL> commit;

Commit complete.

SQL>

Test2 session log:

login as: oracle

oracle@192.168.56.5's password:

Web console: https://srlab.localdomain:9090/

Last login: Sat Nov 11 17:29:56 2023 from 192.168.56.1

[oracle@srlab ~]$

[oracle@srlab ~]$ . oraenv

ORACLE_SID = [oracle] ? FREE

The Oracle base has been set to /opt/oracle

[oracle@srlab ~]$

[oracle@srlab ~]$ sqlplus test2@srlabplug

SQL*Plus: Release 23.0.0.0.0 - Developer-Release on Sat Nov 11 17:33:16 2023

Version 23.2.0.0.0

Copyright (c) 1982, 2023, Oracle.  All rights reserved.

Enter password:

Connected to:

Oracle Database 23c Free, Release 23.0.0.0.0 - Developer-Release

Version 23.2.0.0.0

SQL> show user

USER is "TEST2"

SQL> select * from global_name;

GLOBAL_NAME

--------------------------------------------------------------------------------

SRLABPLUG

SQL> update demo.ticketsales set capacity=capacity - 800 where id=1;

1 row updated.

SQL> select capacity from demo.ticketsales where id=1;

  CAPACITY

----------

      2000

SQL> rollback;

Rollback complete.

SQL> select capacity from demo.ticketsales where id=1;

  CAPACITY

----------

      1800

SQL> select capacity from demo.ticketsales where id=1;

  CAPACITY

----------

       600

SQL>

Test3 Session Log:

login as: oracle

oracle@192.168.56.5's password:

Web console: https://srlab.localdomain:9090/

Last login: Sat Nov 11 17:33:02 2023 from 192.168.56.1

[oracle@srlab ~]$ . oraenv

ORACLE_SID = [oracle] ? FREE

The Oracle base has been set to /opt/oracle

[oracle@srlab ~]$

[oracle@srlab ~]$ sqlplus test3@srlabplug

SQL*Plus: Release 23.0.0.0.0 - Developer-Release on Sat Nov 11 17:37:09 2023

Version 23.2.0.0.0

Copyright (c) 1982, 2023, Oracle.  All rights reserved.

Enter password:

Connected to:

Oracle Database 23c Free, Release 23.0.0.0.0 - Developer-Release

Version 23.2.0.0.0

SQL> show user

USER is "TEST3"

SQL> select * from global_name;

GLOBAL_NAME

-------------------------------------------------------------

SRLABPLUG

SQL>

SQL> update demo.ticketsales set capacity=capacity - 500 where id=1;

1 row updated.

SQL> update demo.ticketsales set capaoity=capacity - 700 where id=1;

update demo.ticketsales set capaoity=capacity - 700 where id=1

                            *

ERROR at line 1:

ORA-00904: "CAPAOITY": invalid identifier

SQL> update demo.ticketsales set capacity=capacity - 700 where id=1;

update demo.ticketsales set capacity=capacity - 700 where id=1

*

ERROR at line 1:

ORA-02290: check constraint (DEMO.MINIMUM_CAPACITY) violated

SQL> update demo.ticketsales set capacity=capacity - 700 where id=1;

1 row updated.

SQL> select * from demo.SYS_RESERVJRNL_78965;

ORA_SAGA_ID$                     ORA_TXN_ID$      ORA_STATUS$  ORA_STMT_TYPE$

-------------------------------- ---------------- ------------ ----------------

        ID CAPACIT CAPACITY_RESERVED

---------- ------- -----------------

                                 0800210059020000 ACTIVE       UPDATE

         1 -                     500


                                 0800210059020000 ACTIVE       UPDATE

         1 -                     700



SQL> set lines 100

SQL> desc demo.ticketsales

 Name                                                  Null?    Type

 ----------------------------------------------------- -------- ------------------------------------

 ID                                                    NOT NULL NUMBER

 NAME                                                           VARCHAR2(100)

 CAPACITY                                              NOT NULL NUMBER

SQL> commit;

Commit complete.

SQL> select * from demo.SYS_RESERVJRNL_78965;

no rows selected

SQL>


Post a Comment: