Actually, you need to do much better than that.
You need to perform lost update detection.
We must presume (in order to update), you read the data out at some point...
basically, you will:
Update table
Set column1 = :new_column1, column2 = :new_column2, ....
Where primary_key = :primary_key
And column1 = :old_column1
And column2 = :old_column2
and check sql%rowcount (in plsql - or use whatever your API provides to tell you how many rows were updated) to see if you actually succeeded.
to read about this update in context:
<quote src=Expert Oracle Database Architecture>
Lost Updates
A lost update is a classic database problem. Actually, it is a problem in all multiuser computer environments. Simply put, a lost update occurs when the following events occur, in the order presented here:
1. A transaction in Session1 retrieves (queries) a row of data into local memory and displays it to an end user, User1.
2. Another transaction in Session2 retrieves that same row, but displays the data to a different end user, User2.
3. User1, using the application, modifies that row and has the application update the database and commit. Session1¿s transaction is now complete.
4. User2 modifies that row also, and has the application update the database and commit. Session2¿s transaction is now complete.
This process is referred to as a ¿lost update¿ because all of the changes made in step 3 will be lost. Consider, for example, an employee update screen that allows a user to change an address, work number, and so on. The application itself is very simple: a small search screen to generate a list of employees and then the ability to drill down into the details of each employee. This should be a piece of cake. So, we write the application with no locking on our part, just simple SELECT and UPDATE commands.
Then an end user (User1) navigates to the details screen, changes an address on the screen, clicks Save, and receives confirmation that the update was successful. Fine, except that when User1 checks the record the next day to send out a tax form, the old address is still listed. How could that have happened? Unfortunately, it can happen all too easily. In this case, another end user (User2) queried the same record just after User1 did¿after User1 read the data, but before User1 modified it. Then after User2 queried the data, User1 performed her update, received confirmation, and even requeried to see the change for herself. However, User2 then updated the work telephone number field and clicked Save, blissfully unaware of the fact that he just overwrote User1¿s changes to the address field with the old data! The reason this can happen in this case is that the application developer wrote the program such that when one particular field is updated, all fields for that record are ¿refreshed¿ (simply because it¿s easier to update all the columns instead of figuring out exactly which columns changed and only updating those).
Notice that for this to happen, User1 and User2 didn¿t even need to be working on the record at the exact same time. They simply needed to be working on the record at about the same time.
I¿ve seen this database issue crop up time and again when GUI programmers with little or no database training are given the task of writing a database application. They get a working knowledge of SELECT, INSERT, UPDATE, and DELETE and then set about writing the application. When the resulting application behaves in the manner just described, it completely destroys a user¿s confidence in it, especially since it seems so random, so sporadic, and it is totally irreproducible in a controlled environment (leading the developer to believe it must be user error).
Many tools, such as Oracle Forms and HTML DB, transparently protect you from this behavior by ensuring the record is unchanged from the time you query it and locked before you make any changes to it, but many others (such as a handwritten Visual Basic or Java program) do not. What the tools that protect you do behind the scenes, or what the developers must do themselves, is use one of two types of locking strategies: pessimistic or optimistic.
.................
Optimistic Locking
The second method, referred to as optimistic locking, defers all locking up to the point right before the update is performed. In other words, we will modify the information on the screen without a lock being acquired. We are optimistic that the data will not be changed by some other user; hence we wait until the very last moment to find out if we are right.
This locking method works in all environments, but it does increase the probability that a user performing an update will ¿lose.¿ That is, when that user go to update her row, she finds that the data has been modified, and she has to start over,
One popular implementation of optimistic locking is to keep the old and new values in the application, and upon updating the data use an update like this:
Update table
Set column1 = :new_column1, column2 = :new_column2, ....
Where primary_key = :primary_key
And column1 = :old_column1
And column2 = :old_column2
...
Here, we are optimistic that the data doesn¿t get changed. In this case, if our update updates one row, we got lucky; the data didn¿t change between the time we read it and the time we got around to submitting the update. If we update zero rows, we lose; someone else changed the data and now we must figure out what we want to do to continue in the application. Should we make the end user rekey the transaction after querying the new values for the row (potentially causing the user frustration, as there is a chance the row will have changed yet again)? Should we try to merge the values of the two updates by performing update conflict-resolution based on business rules (lots of code)?
The preceding UPDATE will, in fact, avoid a lost update, but it does stand a chance of being blocked¿hanging while it waits for an UPDATE of that row by another session to complete. If all of your applications use optimistic locking, then using a straight UPDATE is generally OK since rows are locked for a very short duration as updates are applied and committed. However, if some of your applications use pessimistic locking, which will hold locks on rows for relatively long periods of time, then you will want to consider using a SELECT FOR UPDATE NOWAIT instead, to verify the row was not changed and lock it immediately prior to the UPDATE to avoid getting blocked by another session.
There are many methods of implementing optimistic concurrency control. We¿ve discussed one whereby the application will store all of the before images of the row in the application itself. In the following sections, we¿ll explore three others, namely
* Using a special column that is maintained by a database trigger or application code to tell us the ¿version¿ of the record
* Using a checksum or hash that was computed using the original data
* Using the new Oracle 10g feature ORA_ROWSCN
</quote>