Skip to content

3.0 RFC: Transaction Isolation Level Abstraction #3136

@ionas

Description

@ionas

When using regular find() shortly followed by save() data might have changed in-between.

One option to counter this in some cases is to use updateAll() (atomic saves having conditions specified). Having a save() taking an optional 'conditions' option may be an idea. Some DBA's might not support required Isolation Levels, so this might work for some cases.

The other way to counter this, as recommended on IRC, is to set the Isolation Level on the DataSource and then use SQL Transactions. Now http://book.cakephp.org/2.0/en/models/transactions.html does not mention the Isolation Level. I assume you can set it through Model::query() in 2.x.

Aside the optional 'conditions' for save() two things might be improvable:

A.) The docs around save*() should mention that find() + save() does not handle possible race-conditions and point to the book's chapter on using transactions in cakephp. The docs around updateAll() should point there as well. The chapter about transactions should have a small paragraph around isolation levels, also linking to maybe, wikipedia's entry on database isolation levels: http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels

B.) There should be a way to get and set the Isolation level for the DataSource e.g.:

$DataSource->isolationLevel('SERIALIZABLE'); // set isolationLevel for the Datasource to SERIALIZABLE
$DataSource->isolationLevel(); // get isolationLevel for the Datasource;

As a setter isolationLevel() should supply an abstraction across MySQL (InnoDB), MS SQLServer, PostGreSQL mapping a predefinded list of possible Isolation levels to the specific DBMS calls. If an equivalent IsolationLevel is not specified/possible, it should return false else it should return true.

Optional: A 2nd param could be set ($options) - the first option I can think of is SESSION vs GLOBAL (at least MySQL) supports that - where the isolationLevel is set GLOBAL or for the current SESSION only. Not sure if this is a good idea though.

As a getter (if no parameters are specified) it should simply return the current isolation level (per default specified by the DataSource's implementation) - maybe it should return an array which reports cake's isolation key as well as the internal isolation call executed and maybe also if it is a SESSION or GLOBAL setting (see below).

I can take care about the documentation changes, see point A.) (have to figure it out a bit, last time I worked on the book it had a web interface).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions