[Boulder Ruby Group] ar validations licking the balls
Peter Williams
pezra at barelyenough.org
Fri Nov 9 19:21:37 EST 2007
Tony Arcieri wrote:
> If you could get a table level lock, then checking the uniqueness of a
> value before performing an insert/update could be an atomic, as well as
> performing a find_or_create_by type operation
This approach would work but I have a hard time imagining wanting to
take the performance hit of a table lock on any operation that happens
often enough to make this race condition a real issue.
A workable approach for the case of find_or_create is to enforce the
uniqueness with a database constraint and do this in ruby code:
1. do a find
2a. return the model object if you found it
2b. if it does not exist try to insert it
3a. if the insert succeeds return the new object
3b. if the insert fails re-run the find and return the result of
that.
We use this pattern in a couple of the high volume models where I work
and it works quite well. With PostgreSQL, can achieve this by creating
a "savepoint" before attempting the inserts and then rolling back to
the savepoint if the insert fails.
For normal inserts and updates you could rely on database constraints
for the data integrity, but use validations for pretty error messages.
AR could then detect an insert/update failure and, in that case, it
could rerun the validations to figure out the appropriate message(s).
The validations could even be mechanically created from the database
constraints in many cases (see http://drysql.rubyforge.org/ for an
example of this).
Peter Williams
More information about the Bdrg-members
mailing list