[Dbix-class] is it safe use find_or_create in "read committed" transaction level

Peter Rabbitson rabbit+dbic at rabbit.us
Fri Sep 24 14:40:58 GMT 2010

Bill Moseley wrote:
> On Mon, Sep 20, 2010 at 2:43 AM, Peter Rabbitson <rabbit+dbic at rabbit.us 
> <mailto:rabbit%2Bdbic at rabbit.us>> wrote:
>     3) We try to create the row first, going in blind. This is a good idea
>     in theory, however it has a nasty side effect that it makes the current
>     transaction no-longer-commitable. So using transactions in a race-prone
>     environment is out as well (the user sees random transactions failing
>     for no apparent reason)
> What if DBIC did the create_or_select type of call if not currently in a 
> transaction, otherwise fall back to #1?  Would that be generic enough to 
> help with the issue?

Certainly it can be done (the "are we in a transaction" state is precisely
monitored in the storage object). However there is one more caveat - you
can not reliably tell *why* the thing failed (duplicate or something else?).
So I guess the proper way would be to:

attempt insert
  if exception - attempt select
    if nothing found attempt insert again so you propagate the correct exception

> Frankly, I'm a bit shocked by how often I'm seeing the race condition 
> hit.  Obviously, find_or_create is a useful and needed convenience, so 
> making it a bit less likely to fail would also be convenient.

Come to #dbix-class to get more info on how to actually write this


More information about the DBIx-Class mailing list