Serializable or For Update
December 27, 2007 - 7am Central time zone
Reviewer: Robert C
Hi Tom,
Thanks for the great response. I'm a firm advocate of the third option and use it extensively in my
designs, where necessary of course.
Would I be correct to say that in the case of options one and two mentioned above, the serializable
isolation level would be insufficient to enforce these rules, and only the use of For Update can
correctly ensure integrity.
Also, is it true that in Oracle, unlike SQL Server, if you update a subset of, or insert a new set
of rows using a single column condition, and where no index exists on the column, Oracle will still
only acquire a row level lock?
For example:
Session A
SQL> create table test (id number);
Table created.
SQL> insert into test values (1);
1 row created.
SQL> insert into test values (4);
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test for update;
ID
----------
1
4
Using a new connection, Session 2, (SQL Plus Session 1 is still connected):
SQL> select * from test;
ID
----------
1
4
If I were to try to update one of these two rows, I would be blocked by Session 1 as expected.
However, my initial thoughts were that I would still be blocked if I were to attempt to insert rows
into this table, as there are no indexes present with which Oracle can use to acquire a key range
lock. It appears though, that I can indeed continue to insert new rows from session 2:
SQL> insert into test values (2);
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test;
ID
----------
1
4
2
We now continue in Session 1:
SQL> commit;
Commit complete.
SQL> select * from test;
ID
----------
1
4
2
Does Oracle lock at the row level in all such situations. I ask because I've come from using SQL
Server for a few years, where the following situation does occur:
SQL Server
Session 1:
// New table, no rows, and no other connections at this time
Insert into test values (1);
Session 2:
Insert into test values (2);
The result would be Session 2 is blocked by Session 1.
Thanks Tom
Followup December 27, 2007 - 9am Central time zone:
... Would I be correct to say that in the case of options one and two mentioned
above, the serializable isolation level would be insufficient to enforce these
rules, and only the use of For Update can correctly ensure integrity. ...
correct that serializable is insufficient.
more correct to say that LOCK TABLE is typically called for.
we are not sql server, we do not suffer from their locking issues.
You would only be blocked from inserting in the even of a duplicate UNIQUE value.
eg:
create table t (x int primary key, y int );
session 1: insert into t values ( 1, 1 );
session 2: insert into t values ( 2, 2 ); <<=== no problem
session 2: insert into t values ( 1, 1 ); <<=== this'll block on session 1 tho
Without an index...
December 27, 2007 - 6pm Central time zone
Reviewer: Robert C
I had always understood Oracle (SQL Server also behaves in this way) to allow concurrent inserts
into a table if an index is available. I'm curious to whether this is possible without an index, as
in my example above.
Without an Index
create table test (x int, y int).
SQL Server
Session1: Insert test values (1,1)
Session2: Insert test values (2, 2) // That'll be blocked by
Oracle (From my example above)
Session1: Insert into test values (1, 1)
Session2: Insert into test values (2, 2) // No Issue
Witho an Index
create table test (x int primary key , y int).
SQL Server
Session1: Insert test values (1,1)
Session2: Insert test values (2, 2) // This will succeed
Oracle (From my example above)
Session1: Insert into test values (1, 1)
Session2: Insert into test values (2, 2) // This will succeed
I'd just like to ensure that I understand how Oracle will behave in this situation when there is no
index available. To relate my question to a real world example, in my previous role there was the
requirement to lock a range of values (from a foreign key column) while some calculations were
being performed. The range (not rows) had to be locked as there was the possibility that the
transaction would insert new rows into the range based on the results of the calculations.
Eg. SQL Server
create table myTable (x int primary key, y int foreign key myLookup (id))
insert into myLookUp values (1)
insert into myLookUp values (2)
insert into myTable values (1, 1)
insert into myTable values (2, 1)
insert into myTable values (3, 2)
insert into myTable values (4, 2)
Now, in Session One we wish to lock the range of rows (and prevent any inserts of new rows) for the
foreign key values of 1 for column Y in myTable. In SQL Server can accomplish this using the
serializable transaction level:
Session1: set transaction isolation level serializable
Session1: select * from myTable where y = 1
Session2: insert into myTable values (5, 2) // Insert succeeds
Session2: Insert into myTable values (5, 1) // Blocked by the range lock held by Session1.
Session1: Performs various calculations on myTable and then decides to insert the following row.
Session1: Insert into myTable values (5, 1) // Succeeds.
In Oracle, how can I achieve this same type of lock? Ie, only lock on the range of 1 for the y
column. In SQL Server, if I were to remove the unique index from myLookUp, then in the above
scenario, SQL Server would lock the entire myTable table.
Thanks,
Followup December 28, 2007 - 3pm Central time zone:
regardless of an index - oracle has pretty much always allowed for concurrent insert
the only time this would not be true is when you have a UNIQUE constraint (primary key, unique index) in place - then two sessions might serialize upon attempting to insert the same value.
and in sqlserver, I believe back in the days of page level locking, you needed a clustered index to sometimes permit concurrent inserts. To spread the data around so the inserts did not go after the same block
Code for locks? Against an Oracle databasse?
December 27, 2007 - 9pm Central time zone
Reviewer: Chuck Jolley from OKC, OK USA
To quote Yoda: You must unlearn what you have learned.
I have been programming against Oracle for 9 years and in that time I have not coded one single
lock, not even a select for update.
Not one single time in hundreds of thousands of lines of code.
There is about a 99.99% chance you can simply forget about locks.
Unless you have some awfully bizarre business rules this will simply not be an issue.
I'm sure Tom will give you examples and such, but really, the table will look to each session just
the way you would intuitively expect it to.
Followup December 28, 2007 - 3pm Central time zone:
you have to think about 'locks' when you have lost update possibilities.
search this site for 'lost update' for more discussion
To the above poster...
December 27, 2007 - 10pm Central time zone
Reviewer: Robert C
To the above poster: Of course I'm not against using a database for locking. The essence of my
message was to correctly understand the locking behaviour of the Oracle database in certain
situations to determine whether or not explicit locking is necessary.
Coming from an SQL Server background and with a solid understanding of database theory, I merely
wish to ensure that my understanding of Oracle's implementation of database transactions is
correct. With such an understand, I will be able to ensure that my decisions are correct and are
based on fact rather than the risk of misunderstanding.
As you will know, Oracle writers are not blocked by readers, as is the case with SQL Server. Hence,
transactions need to be developed differently to address this difference. It is this very
difference that I'm trying to clarify here with my questions.
With respect to your claim that the select for update clause is seldom used in reality, I will have
to strongly disagree with you here, based on common sense and experience. In the case of the
former, I find it impossible to comprehend that the select for update clause is used as the
exception. If you expect two rows to modify the same subset of rows, the select for update clause
should be used.
Consider the overlapping date problem rule, or any such transactions that requires an insert to be
based wholly on the contents of the set to which the insert will be made. If the select for update
clause were not to be implemented in this case, the following could occur:
Session1: Select data to read (no overlap exists)
Session2: Select data to read (because session2 will not be blocked by other transactions, it also
does not detect an overlap)
Session1: Proceeds to insert a row
Session2: Proceeds to insert a row
After both transactions have committed, we will find that the rule has, in fact, been violated. Now
in order to avoid this situation, the select for update clause must be used.
For another example, please see my above question.
Of course as with any discussion, my claimed understanding may be incorrect, and it is for the
presence of this possibility that I am asking these very questions.
Followup December 28, 2007 - 3pm Central time zone:
...
Consider the overlapping date problem rule, or any such transactions that
requires an insert to be based wholly on the contents of the set to which the
insert will be made. If the select for update clause were not to be implemented
in this case, the following could occur:
...
ah - but - you cannot lock that which you cannot see. You need to either lock the table OR lock a row in a parent table for this overlapping date issue (this is the example I used in my last book expert oracle database architecture in fact!)
To the above poster (2)
December 27, 2007 - 10pm Central time zone
Reviewer: Robert C
I also forgot to ask: Did you read Tom's reply to my first follow up, in which he quite clearly
points out that explicit locking is in fact required to enforce certain rules.
I'm really struggling to understand your view here.
Followup December 28, 2007 - 3pm Central time zone:
explicit locking is needed in many real world cases - be is pessimistic (select for update) or optimistic (use a timestamp, ora_rowscn or something similar)
yes.
Taking the piss?
December 27, 2007 - 10pm Central time zone
Reviewer: Robert C
To the above poster:
You say, quote:
I have been programming against Oracle for 9 years and in that time I have not coded one single
lock, not even a select for update.
Not one single time in hundreds of thousands of lines of code.
There is about a 99.99% chance you can simply forget about locks.
end quote
Ah.. It has only just occurred to me that your above quote was said in jest. For to suggest that
one can simply just "forget about locks" would be grossly irresponsible.
Possible to edit your comments before a followup has been posted?
December 28, 2007 - 1am Central time zone
Reviewer: Robert C
Just a very important point I need to clarify, for I didn't explain it very clearly earlier. When I
mentioned that SQL Server can lock a range of values, I actually meant to say that SQL Server can
prevent an insert into a range of values if the query includes a predicate that specifies a
foreign key value.
Apologies for the confusion.
Tom,
What is your view on extending the functionality of AskTom to enable users to make amendments to
their follow ups to a question?
Followup December 28, 2007 - 3pm Central time zone:
since I don't have you "login", it would not really be feasible.
and I don't want to make you "login"
Not Kidding
December 28, 2007 - 2pm Central time zone
Reviewer: Chuck Jolley from OKC, OK USA
I wasn't kidding, I have never coded an explicit lock against an Oracle database.
I didn't mean you could generically "forget about locks"
But if you handle your transactions properly locking will not be something you spend much time
worrying about in an Oracle database.
Followup December 28, 2007 - 3pm Central time zone:
well, truth be told, I sort of disagree - especially in a stateless web environment... Lost updates abound.
Stateless programming - Yech
December 28, 2007 - 4pm Central time zone
Reviewer: Chuck Jolley from OKC, OK USA
There is that.
We only have a couple of small web interfaces to our database and collisions are not in the cards
there simply because of the business rules, ie there is nothing to collide.
So I haven't had to deal with that problem.
Followup January 1, 2008 - 5pm Central time zone:
and if you use something like APEX - you don't have to - it does the optimistic concurrency control for you.
But I would say "stateless - not yech - but the way it is"
asktom is totally stateless from a database connection perspective, but we use APEX to manage and maintain the state for us.
Editing the posts
February 14, 2008 - 3am Central time zone
Reviewer: Radhakrishna from Singapore
since I don't have you "login", it would not really be feasible.
and I don't want to make you "login"
Tom - First line is fine, but for the second line, any reason for not wanting to have a login?
Thanks
Radhakrishna
Followup February 14, 2008 - 9am Central time zone:
because it would be ANNOYING for you
and it would bug the #@%#@%#@ out of me as people email me with "i cannot log in, i forgot my name, i forgot my password, ....."

February 14, 2008 - 10am Central time zone
Reviewer: A reader from UK
"because it would be ANNOYING for you
and it would bug the #@%#@%#@ out of me as people email me with "i cannot log in, i forgot my name,
i forgot my password, ....."
.. I know it's extra work, but these tasks can be automated without your interference
I think what I would like to see is advance notice on the home page that 'Tom may accept new
question on so & so date at this time for x minutes...' because many time we have new question for
you but we end-up posting in one of your follow-up because of lack of access to new question sets.

February 15, 2008 - 4am Central time zone
Reviewer: Robert C
Many years ago when I was young (I'm 25 now), I almost invariably found the ask a question process
unavailable. Living in Brisbane at the time however, I did have the time differences against me.
Over Christmas and the New Year of 2007 / 2008 I found that the option to ask a question was
frequently available. Perhaps you just need to visit the site during a festive period?
Followup February 15, 2008 - 8am Central time zone:
or a period of time when I'm not traveling so much :)
Internet Cafe at the Airport
February 20, 2008 - 7am Central time zone
Reviewer: Robert
Tom,
Could you not log onto AskTom from one of the Internet Cafes at the Airport?
|