We have a clustered Java application running over a mysql 5.5 database, InnoDb engine. The app uses Spring with transaction isolation level set to SERIALIZABLE
.
Inside a method, which might be executed concurrently, either in different threads of one node or in separate nodes, there's a typical SELECT-then-UPDATE pattern. Here's the pseudo-code:
old_status = null;
do {
old_status = SELECT status
FROM bookings
WHERE code=123;
affected_rows = UPDATE bookings
SET status=<new_status>
WHERE code=123 AND status=<old_status>;
} while (affected_rows == 0);
// Now we can do stuff with <old_status> value
Field code
is the PK; <old_status>
and <new_status>
values are always different.
The SELECT
and the UPDATE
run on separate transactions.
This works pretty well. I even think that the AND status=<old_status>
checking in the WHERE
clause of the UPDATE
statement is unnecesary, since transaction isolation level is SERIALIZABLE
, meaning that it would be safe to issue the SELECT
and then the UPDATE
without checking the value of the status
field.
So, first question: (1) Am I OK in that all this is unnecesary when transaction isolation level is SERIALIZABLE
?
Now, what happens is that a few days ago, the DBA suddenly materialized in my workplace and came with arguments and metrics that 'proved' we should start to use READ_COMMITED
transaction isolation level. As he almost never leaves his catacomb, I immediately knew that he was being serious. He said that if we changed transaction isolation level from SERIALIZABLE
to READ_COMMITED
, cpu's usage would descend by 10% and that queries would run lot way faster, etc. In short, he had his arguments to make us switch to READ_COMMITED
transaction isolation level.
So, second question: (2) Can we happily switch to READ_COMMITED
transaction isolation level, given we are already checking the value of the status
field in the WHERE
clause of the UPDATE
sentence by means of AND status=<old_status>
?
I think we can, but would like to check with the community first. Thanks in advance!
Note: I can't use native constructs, such as mysql's SELECT ... FOR UPDATE, etc.