Am Samstag, 9. Januar 2016 06:33:50 UTC+1 schrieb [email protected]:
>
> > Pessimistic locking, the way you want to use it, decreases performance 
> because all reads have
> to wait until the lock is gone. For the web this is realy a bad thing. 
> Futhor more the chance of a deadlock
> is every time ahead of you.
>
> Reads should not be locked by a FOR UPDATE lock (
> http://www.postgresql.org/docs/9.4/static/explicit-locking.html#LOCKING-ROWS).
>  
> I agree potential dead-locks are a problem if you have slightly complicated 
> hierarchies in your transactions. 
>

It's database and isolation level depenentend if the lock will also block 
reads (for instance mysql can block reads 
http://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html)


 

>
> > And worst of all, such a pessimistic lock can take a undetermined amount 
> of time.
> During a Request this can lead to timeouts on client site. Handle client 
> timeouts 
> can be a nightmare too.
>
> That's only undermined if there is an open transaction which holds that 
> lock for an undetermined time right? 
>

Not only. Even if you'r transaction is determined, you don't know how many 
transactions are handled parallel and all
updates with "select for update" have to wait until the previous 
transactions are finished.

 

> Heroku for examples gives only 30 seconds to a db connection but generally 
> you would have to monitor the locks. 
>

But how long does a user wait until he press abort or reload? That's 
another issue you have to keep in mind and 30 seconds is a realy long time
for a web request.
 

>
> > In this case I would still use optimistic locking. You can simply call 
> .touch on the associated object (in both transaction), so the lock_version
> is increased.
>
> So if I understand correctly your over-all suggestion is to .touch all 
> Objects involved in validations which otherwise would not have been written 
> to in the current transaction. Although it seems touch updates the 
> updated_at column (this can be worked-around I suppose). One concern here 
> is if there are a number of validations each one has to remember to .touch 
> on the object - and if the same object is used in multiple validations that 
> will touch multiple times in one transaction. 
>

Generaly spoken it is true, but like every time it depends on you 
implementation what can be done to simplify this. For instance you can use 
service objects or interactors to overcome 
this limitation. But I think a discussion into this direction is out of 
scope of the general discussion about pessimistic locking. So I have to 
say, yes, you have to touch all objects which
are used within such a validation and it can result in multiple updates for 
one record only to increase the lock_version. 


 

>
> On Friday, January 8, 2016 at 7:13:47 PM UTC+8, Dieter wrote:
>>
>> In this case I would still use optimistic locking. You can simply call 
>> .touch on the associated object (in both transaction), so the lock_version
>> is increased.
>>
>> Pessimistic locking, the way you want to use it, decreases performance 
>> because all reads have
>> to wait until the lock is gone. For the web this is realy a bad thing. 
>> Futhor more the chance of a deadlock
>> is every time ahead of you.
>>
>> And worst of all, such a pessimistic lock can take a undetermined amount 
>> of time.
>> During a Request this can lead to timeouts on client site. Handle client 
>> timeouts 
>> can be a nightmare too.
>>
>> But that's only my opinion.
>>
>> Am Freitag, 8. Januar 2016 11:29:29 UTC+1 schrieb [email protected]:
>>>
>>> Sorry, yes you are correct that was a poor example and for that 
>>> particular condition optimistic locking will validate correctly. On the 
>>> other-hand conditions which use data from a reference but do not update 
>>> that reference will still be able to race .e.g. 
>>>
>>> A fulfillment has fulfillment_line_item's which check that 
>>> fulfillment.status != 'shipped' to validate a destroy on a 
>>> fulfillment_line_item. This later case will validate on the stale 
>>> fulfillment.status - but since only the fulfillment_line_item (not the 
>>> fulfillment) is to be updated in such a transaction no error will be noted 
>>> even if fulfillment.lock_version has changed (since no update to the parent 
>>> would have been attempted). 
>>>
>>>
>>> On Wednesday, January 6, 2016 at 4:27:46 PM UTC+8, Dieter wrote:
>>>>
>>>> You problem hast nothing todo with multiple dynos. This race condition 
>>>> can occour as soon as you have multiple workers or threats (whatever your 
>>>> server uses). But
>>>> its a normal issue and in my point of view you can handle it with 
>>>> optimistic locking just fine.
>>>>
>>>> When you use optimistic locking rails prepends on every update und 
>>>> delete (when you use object.destroy) a "AND locking_version=?", 
>>>> object.locking_version.
>>>>
>>>> In your case when your #update transaction happens it's gets for 
>>>> instance lock_version 1 and also your #delete transaction gets 
>>>> lock_version 
>>>> 1.
>>>>
>>>> Say the #delete transaction is faster so you will get an 
>>>> ActiveRecord::StaleObjectError within you #update action or vice versa.
>>>>
>>>> You only have to handle the ActiveRecord::StaleObjectError. Without 
>>>> handling this error the transaction will be rolledback (the slower one)
>>>>
>>>> But this is only true as long as you use a Isolation level which does 
>>>> not read UNCOMMITTED data.
>>>>
>>>> This should be the default in most cases.
>>>>
>>>> You can test it this way (as long as you dont use rails identy map).
>>>>
>>>> # use same id for find
>>>> fulfillment1 = Fulfillment.find 1
>>>> fulfillment2 = Fulfillment.find 1 
>>>>
>>>> fulfillment1.status = '...'
>>>>
>>>> fulfillment2.status = '...'
>>>>
>>>>
>>>>
>>>> fulfillment1.save!
>>>>
>>>> fulfillment2.save! # should raise an exception, take a look at the 
>>>> generated SQL-Statement
>>>>
>>>> regards 
>>>> dieter
>>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" 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 https://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Reply via email to