I didn't know that SELECT locks even false hits within serializable 
transaction, thanks
Also, the re-submision (both  automatic or initiated by user) is brilliant

Thanks!

W dniu piątek, 20 grudnia 2013 22:12:32 UTC+1 użytkownik Constantin-Emil 
Marina napisał:
>
> You could use pessimistic locks in a transaction for validation AND have 
> an index on the e-mail field:
>
> http://docs.doctrine-project.org/en/2.0.x/reference/transactions-and-concurrency.html
> In a serializable transaction, read queries lock index ranges explored by 
> a SELECT, even false hits.
>
> It's a bit more complicated than just dealing with the exception; also 
> note that you are taking a bit of a responsability on your hands: as your 
> model gets increasingly complicated ACID exceptions are bound to occur, 
> unless you use a really aggressive locking strategy; you'd need to validate 
> and version (see optimistic locking) absolutely every piece of data that's 
> about to get written (including relations etc), and to be able to do that 
> is kind of a birth gift for complicated models. However, since such 
> conditions are remote, I use a generic handle that just re-submits the 
> request. This way, you don't have to parse the exception to know what 
> really happened: on the second pass, the duplicate email address will pe 
> picked up in the validation (read) phase and an appropriate message will be 
> displayed tothe user. This can be done either automatically or manually by 
> the user (in case some exception occurs, prompt him a generic message 
> kindly asking him to try again).
>
> On Friday, December 20, 2013 4:35:20 PM UTC+2, Adam Zielinski wrote:
>>
>> I have a entity called Contact with a single unique field email. Before 
>> persisting, I am validating values to make sure my unique constraint won't 
>> be violated. 
>>
>> Let's assume I want to persist a Contact with an email 
>> [email protected], of course it works. Then I try again and bam, 
>> validation kicked in, I know the insert is not going to work, and I can 
>> show nice error message right next to my "email" field. Perfect!
>>
>> Now I want to add another contact, this time with an email 
>> [email protected], but oops, someone decided to add the same email 
>> in exactly the same moment as me. That's okay, it happens. Both requests 
>> are processed like this:
>>
>>  |   My Request    |   Other Request-+-----------------+-----------------1|  
>>  Validation    |    Validation    2|   $em->flush()  |    $em->flush()
>>
>> In both cases validation passed since the Contact entity with such email 
>> wasn't in database yet. This leads to two Insert queries sent with the 
>> same email. MySQL will prevent the second one, so Doctrine will throw an 
>> exception, user will see error 500 instead of "Email has been already 
>> taken". Documentation says I should avoid database exceptions at all cost, 
>> but this time database exception is perfectly okay, there is no way I can 
>> tell if this insert will succeed other than performing an insert.
>>
>> My question is: *What is the Doctrine Way **(tm) to **recover from that 
>> exception **elegantly**?* I just want to tell the user that he have to 
>> type in different email address *(and I don't want to set an exclusive 
>> lock for the entire table).*
>>
>> I could of course do something like this:
>>
>> try {
>>     $em->flush();} catch (DBALException $e) {
>>     $pdoException = $e->getPrevious();
>>     if ($pdoException &&
>>         $pdoException instanceof PDOException &&
>>         $pdoException->getCode() === '23000'
>>     ) {// let the form know about the error
>>     } else throw $e;}
>>
>> But that's wrong, requires copy-pasting the code each time I have to deal 
>> with unique constraints, and is trouble in case there is more than one 
>> unique index. *Is there any built-in component that will parse the 
>> MySQL/PostgreSQL/whatever error message and tell me "hey you violated this 
>> and this constraint"?*
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"doctrine-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/doctrine-user.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to