[Dbix-class] Insert or Update (was ANNOUNCE: 0.08099_08)

Jess Robinson castaway at desert-island.me.uk
Sat Apr 18 10:35:43 GMT 2009


On Wed, 15 Apr 2009, Peter Rabbitson wrote:

> Tim Bunce wrote:
>> On Mon, Apr 13, 2009 at 11:20:41AM +0100, Peter Corlett wrote:
>>> On 13 Apr 2009, at 09:35, Tim Bunce wrote:
>>> [...]
>>>> If you use SELECT FOR UPDATE then savepoints aren't required for a safe
>>>> implementation, right?
>>> No.
>>
>>> Critically though, if the SELECT does not return any rows, nothing is
>>> locked and the race remains.
>>
>> Got it.
>>
>>> So it looks like this still needs savepoints to do correctly.
>>
>> Should everyone have to pay the overheads, though, even if they don't
>> need atomic behaviour? Perhaps add an update_or_create_atomicaly() method.
>
> No more methods please, it's a mess as it is. My vote is for correctness,
> besides update_or_create is a non-widely used method. My feeling is that
> people who really need speed, use their own *_or_* logic, as it can done
> made much more efficient in software (I myself do table pre-reads within
> an isolated transaction).

In the spirit of that, instead of bloating DBIC more at this level, leave 
it as is, and add a Component, would be my preference. Then people can 
have it or not, their choice.

> So if update_or_create can be implemented atomically, and not break
> backwards compatibility I am all for it.

AND in a way where the code runs sanely on all(!) databases, or we have to 
move it into the Storage layers instead.

Some DBs do support nested transactions, and some don't support 
savepoints, so it sounds like it wants to be in the Storage layer(s) 
anyway. (And not many support the "FOR UPDATE" clause, with that exact 
syntax, or at all)

>> Alternately, enhance update_or_create() as you propose and someone else
>> could implement a ...::FastResultSet moose role that provides an
>> update_or_create_fast() method that avoids the initial SELECT by
>> attempting an UPDATE as the first step.
>
> There are actually many places in DBIC where this could be done. One
> definitely is the multicreate code, which traverses the relationships up
> and down multiple times, just to make sure it DTRT. This protection can
> very well be dropped, but only per explicit users request.

That sounds like overkill.. keep dbic simple, add layers on top, eg 
components or an entire "dbic atomic" component set/layer. This is why 
dbic is so extendable, so we dont have to dig around in the innards to add 
bits..

Jess




More information about the DBIx-Class mailing list