errors on transactions and locks ? - Mailing list pgsql-hackers

From Jose' Soares Da Silva
Subject errors on transactions and locks ?
Date
Msg-id Pine.LNX.3.96.980420100710.554A-100000@proxy.bazzanese.com
Whole thread Raw
List pgsql-hackers
Hi, all

I have some problems with transactions and locks...
I have 5 questions about it...

1. NOTICE:  (transaction aborted): queries ignored until END
   *ABORT STATE*
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   I would like to know what's mean the above message.
    - Seems that transactions aborts at smallest syntax error ?
    - Seems that every work done until this point is lost.
    - ?Am I right?
    - If yes, ?what can I do to go on?
      Seems that I can't do nothing but COMMIT or ROLLBACK.
    - Seems that COMMIT has the same effect of ROLLBACK,
      because all changes are lost in anyway.
    - If that's true  ?why is it neccessary to do COMMIT or ROLLBACK?
    - and ?what about locks?
      ?are all locks released before COMMIT/ROLLBACK?

2. LOCKED FOR EVER AND EVER...
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   If user2 try to SELECT a table locked by user1, user2 falls in a trap
   he can't do nothing to free himself from this trap,
   and he must wait that user1 ends his work.

   - ?Is there a way to avoid this trap?
   I think that's useless to lock tables even for readonly operations.
   - user2 shouldn't be able to UPDATE tables but he should be able
     to SELECT tables.
   - ...or at least user2 should have the possibility to choice if
     he wants wait for ever that a table become available or retry latter
     to see if table was unlocked.
     A message like:
          "TABLE <tablename> IS LOCKED BY USER <username> PLEASE, TRY LATTER"
     would be preferable.
   - If this interests to someone;
             the Oracle'sLOCK TABLE <tablename> IN EXCLUSIVE MODE
     allows read access to locked tables.

3. DROP TABLE <tablename> or DELETE FROM <tablename> ?
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   Dropping a table inside a transactions and then rolling back the work
   is equivalent to DELETE FROM <tablename>; the table's structure will
   be restored but data will be lost:

   postgres=> begin;
   BEGIN

   postgres=> select * from cities;
   code|city
   ----+-------------
   SFO |SAN FRANCISCO
   STL |ST. LOUIS
   (2 rows)

   postgres=> drop table cities;
   DROP

   postgres=> rollback;
   ABORT

   postgres=> select * from cities;
   code|city
   ----+----
   (0 rows)

4. MIRACLE DROPPED TABLE IS RETURNED.
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   User <manuel> dropps a table inside a transactions while
   user <jose> is trying to query the same table,
   user <manuel> change his mind and rolls back the work,
   at this point user <jose> see the result of his query,
   and insert a new row to the table.
   At this point the dropped table returns with all its data.

 --user: manuel-------------------------------------------------

   postgres=> select current_user;
   getpgusername
   -------------
   manuel

   postgres=> begin;
   BEGIN

   postgres=> select * from cities;
   code|city
   ----+-------------
   SFO |SAN FRANCISCO
   STL |ST. LOUIS
   (2 rows)

   postgres=> lock cities;
   DELETE 0

 --user jose--------------------------------------------------

   postgres=> select current_user;
   getpgusername
   -------------
   jose

   postgres=>  select * from cities;
   --jose was caught in a trap, wait for ever and ever ...

 --user manuel again---------------------------------------------

   postgres=> drop table cities;
   DROP

   postgres=> rollback;
   ABORT

 --user jose again---------------------------------------------
 -- (finally jose is "free" and have his query result):

   code|city
   ----+-------------
   SFO |SAN FRANCISCO
   STL |ST. LOUIS
   (2 rows)

 -- and now, jose decide to append a new row to the table...
   postgres=> insert into cities values ('SJC','SAN JOSE');
   INSERT 460390 1

 --and user manuel query table... ------------------------------------------
 -- et voila'... the table and all its data are returned...
   postgres=>  select * from cities;
   code|city
   ----+-------------
   SFO |SAN FRANCISCO
   STL |ST. LOUIS
   SJC |SAN JOSE
   (3 rows)

5. LOCK AT ROW LEVEL
   ^^^^^^^^^^^^^^^^^
   Massimo Dal Zotto have done a very useful work with locks at row level
   (refer to .../contrib/userlock) and it should be interesting to implement
   these functions as SQL statements.

   --to lock a row(s)...
   SELECT user_write_lock_oid(OID), oid, *
      FROM cities
      WHERE city LIKE 'SAN%';

   user_write_lock_oid|   oid|code|city
   -------------------+------+----+-------------
                     1|460388|SFO |SAN FRANCISCO
                     1|460390|SJC |SAN JOSE

   --if result of "user_write_lock_oid" is 1, then the row(s) are available
   --and you can update it...

   --to unlock the row(s)...
   SELECT user_write_unlock_oid(OID)
      FROM cities
      WHERE oid = 460388 OR oid = 460390;

   - If this interests to someone, Oracle uses a similar way to locking rows,
     take a look...

   SELECT ROWID, *
      FROM cities
      WHERE city LIKE 'SAN%';
      FOR UPDATE OF city;

    ROWID    CODE    CITY
   __________________________________
   460388    SFO     SAN FRANCISCO
   460390    SJC     SAN JOSE

   --if row(s) is/are available then you can update it/them...

   UPDATE cities
      SET city = INITCAP(city)
      WHERE rowid = 460388 OR rowid = 460390;

   --to unlock the row(s)...
   COMMIT

   Oracle uses ROWIDs to lock rows, we also have OIDs...
   ?How much difficult is it to implement ?

                                                            Ciao, Jose'


pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: [HACKERS] Proposal for async support in libpq
Next
From: "Jose' Soares Da Silva"
Date:
Subject: RE: [HACKERS] drop table inside transactions