[Catalyst] Duplicate entries with C::P::Session::Store::DBIC
and MySQL - new findings
abuse at cabal.org.uk
Tue Aug 26 11:14:21 BST 2008
On Tue, Aug 26, 2008 at 09:47:59AM +0200, Tobias Kremer wrote:
> b) Patch DBIx::Class's find_or_create() method and reverse its order
> (insert first, check for duplicate, then select).
> - Not that easy to implement because every database returns
> a different error to signal a unique key constraint violation.
> - It's quite possible that this doesn't really solve the problem
> but just changes the error. If the row is deleted between insert
> and select (this race condition still exists), find_or_create()
> will return nothing and AFAICT C::P::Session::Store::DBIC's
> flash() method expects a working row object.
Also, it'll cancel any transaction in progress. However, that can be fixed
by using SAVEPOINT instead. SAVEPOINT; INSERT ...; ROLLBACK TO SAVEPOINT;
SELECT/UPDATE ...; seems to be the recommended approach for PostgreSQL.
PostgreSQL supports SAVEPOINT as of 8.0; you're SOL with 7.4 and earlier.
(I was in fact considering concocting and submitting a patch as I'm being
bitten by this race condition too.)
I can't speak for whether MySQL's advertised SAVEPOINT support works, or
even does anything other than acknowledge that the keyword exists.
> - find_or_create() will be faster everywhere in many cases.
There would be the overhead of a transaction, but it's a worthwhile cost in
a non-toy application.
More information about the Catalyst