views:

36

answers:

2

Hi all,

I have a problem where I need to keep and increment an object number field in a table, however this number should be unique within given logical domain, not across table globally.

An example would be multiple Businesses scheduling multiple Jobs; Job.Number should be unique within a business.

So I basically need to make sure that concurrent job creation operations do not produce Jobs with the same Number.

Currently I see only one way to implement that (in postresql):

Lock the table with a self-locking type of lock, say "SHARE UPDATE EXCLUSIVE" so all the other operations of this type have to queue and wait, thus ensuring that MAX() function always returns unique value.

However there seems to be a huge drawback in that solution - it essentially creates a bottleneck for all INSERT operations into Jobs table.

I don't think I can use Postgreql sequences, because:

  1. I do not want to create a new sequence for each new business
  2. It can have gaps

would you suggest any other ways to deal with that problem?

Thanks!

+1  A: 

First of all, if all you need is a distinct number, why don't you use a sequence to generate it?

If a shared sequence is not ok, because will generate "gaps" (i.e. Business #1 jobs could be numbered 1,2,5,6,23 and Business #2 jobs could get 4,7,8,20 and so on) or for whatever reason, why don't you build a table of "job counters":

> Business ID | Job Counter 
----------------------------
> Business #1 | 23 
> Business #2 |  3 
> Business #3 | 11
> Business #4 | 76

So when you have to generate the next Job for Business #2 you have to lock only the Business#2 row, increment it, and proceed. Assuming Postgres can lock at the record level, you would make things more scalable this way.

p.marino
A: 

What about SELECT * FOR UPDATE statement?

Also I want to notice that CREATE SEQUENCE has a "CACHE" option, so it can work faster if you worries about some gaps.

nuald
Select * for update is equivalent to a table lock. And a cache on the sequence won't necessarily help with gaps.
p.marino