Sequel (Ruby), how to increment and use a DB counter in a safe way?

为君一笑 提交于 2019-12-05 14:17:05

If you are using PostgreSQL, you can use UPDATE RETURNING: DB[:table].returning(:counter).update(:counter => Sequel.expr(1) + :counter)

However, without support for UPDATE RETURNING or something similar, there is no way to atomically increment at the same time as return the incremented value.

The answer is - in a multithreaded environment, don't use DB counters. When faced with this dilema:

  1. If I need a unique integer counter, use a threadsafe counter generator that parcels out counters as threads require them. This can be a simple integer or something more complex like a Twitter Snowflake-like generator.
  2. If I need a unique identifier, I use something like a uuid

In your particular situation, where you need a count of albums - is there a reason you need this on the database rather than as a derived field on the model?

Update 1:

Given that you're dealing with something approximating file exports with workers on multiple hosts, you either need to parcel out the ids in advance (i.e. seed a worker with a job and the next available id from a single canonical source) or have the workers call in to a central service which allocates transaction ids on a first come first served basis.

I can't think of another way to do it. I've never worked with a POS system, but the telecoms network provisioning systems I've worked on have generally used a single transaction generator service which namespaced ids as appropriate.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!