News for hackers. Stuff that matters.
Re:PostgreSQL anti-patterns: read-modify-write cycles (2014) by isoos on Wednesday December 21, 2016 @05:37AM (#13228133)
I'm glad to see optimistic concurrency control mentioned. In my experience even seasoned developers are unaware of this pattern, which should be really the default in many database-handling code.

I'm not aware of ORMs handling it either (except for my in-house code generator). Is there anything out there that handles it well?

Re:PostgreSQL anti-patterns: read-modify-write cycles (2014) by pmontra on Wednesday December 21, 2016 @07:29AM (#13228564)
Re:PostgreSQL anti-patterns: read-modify-write cycles (2014) by wildmusings on Wednesday December 21, 2016 @11:16AM (#13230213)
From the optimistic locking page: This locking mechanism will function inside a single Ruby process. To make it work across all web requests, the recommended approach is to add lock_version as a hidden field to your form.

Unless I'm misunderstanding, that's absolutely terrible advice, from both a security and proper layering standpoint.

Re:PostgreSQL anti-patterns: read-modify-write cycles (2014) by dcosson on Wednesday December 21, 2016 @02:31PM (#13231913)
> Unless I'm misunderstanding, that's absolutely terrible advice, from both a security and proper layering standpoint.

Not trying to start a flamewar but... that's Rails in a nutshell. The default patterns are just straight up bad for any kind of large app built by more than one or two people. The gotchas mentioned in this post basically have no built-in rails patterns to mitigate them so you have to know how to write an app without the ORM to effectively use ActiveRecord, even though it's viewed as a great abstraction that you should always use so your code stays readable and you and your future team members won't have to worry about the implementation details in SQL.

For instance there's no built-in way to take advantage of Postgres UPSERT so every codebase I've come across does it wrong with a naive read then create (sometimes wrapped in a .transaction block which doesn't necessarily fix it as the post points out but is used as like a rain dance in many rails codebases whenever something's acting weird and we're not sure why). The built-in Rails increment() is not atomic, and the atomic increment_counter() helper still encourages you to do the wrong thing! (it doesn't use UPDATE .. RETURNING so you see people incrementing and then reading which obviously is no longer atomic). And on and on.

Re:PostgreSQL anti-patterns: read-modify-write cycles (2014) by netghost on Wednesday December 21, 2016 @01:19PM (#13231317)
I think if your lock version is a random hash that is updated each time you write via trigger or app code, then at best someone nefarious could change that value in the form and prevent themselves from being able to update the record.

It also depends on what you're trying to achieve. For instance, if you're just trying to help coordinate people updating a wiki page so that two people don't accidentally clobber each other's updates then it's probably not a huge concern.

From a layering perspective, you can probably implement this with checks and triggers in postgres so that it's mostly transparent to the client.

That said, I wouldn't bother myself ;)

Re:PostgreSQL anti-patterns: read-modify-write cycles (2014) by RazerM on Wednesday December 21, 2016 @12:20PM (#13230799)
SQLAlchemy suppports optimistic concurrency control[1] and row level locking[2]

[1]: http://docs.sqlalchemy.org/en/latest/orm/versioning.html

[2]: http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalche...

Re:PostgreSQL anti-patterns: read-modify-write cycles (2014) by agopaul on Wednesday December 21, 2016 @06:49AM (#13228406)
Doctrine2 (PHP) supports this natively.

I've never used this approach, but after working a lot with row-level locks (SELECT ... FOR UPDATE) errors in environments with sustained load, I think next time I'm going to evaluate this approach.

Row-level locks need to be carefully implemented in order to avoid deadlocks, which can occur for a number of reasons (eg. missing indexes, other transactions locking rows in different orders, etc.).

Re:PostgreSQL anti-patterns: read-modify-write cycles (2014) by joemccall86 on Wednesday December 21, 2016 @06:28AM (#13228328)
GORM in Grails uses optimistic concurrency control by default, which is how I learned about the issue in the first place.
Re:PostgreSQL anti-patterns: read-modify-write cycles (2014) by mosburger on Wednesday December 21, 2016 @10:05AM (#13229629)
IIRC Hibernate supports it (haven't used Hibernate in ages though).
Re:PostgreSQL anti-patterns: read-modify-write cycles (2014) by Aaargh20318 on Wednesday December 21, 2016 @11:30AM (#13230358)
JPA 2.0 has both optimistic and pessimistic locking.
Re:PostgreSQL anti-patterns: read-modify-write cycles (2014) by dvlsg on Wednesday December 21, 2016 @01:13PM (#13231276)
Mongoose uses optimistic locking by default, I believe.
Re:PostgreSQL anti-patterns: read-modify-write cycles (2014) by GordonS on Wednesday December 21, 2016 @01:56PM (#13231623)
I believe Marten supports this