nhibernate / nhibernate-core

NHibernate Object Relational Mapper
https://nhibernate.info
GNU Lesser General Public License v2.1
2.13k stars 928 forks source link

NH-3880 - HiLo optimizer for enhanced TableGenerator not Generating next value correctly when called from different processes #1370

Open nhibernate-bot opened 7 years ago

nhibernate-bot commented 7 years ago

Tomas Gerhardsen created an issue:

The hilo optimizer is not calculating the correct id when called from two different processes.

You will get Primary key Violations if you use the enhanced tablegenerator with hilo and two different processes sharing the same db.

Once the optimizer reaches the upper limit of a bucket it should get a new one from db and use it to calculate the new bucket. This does not happen.

The code:

else if (_upperLimit <= _value)
{
  _lastSourceValue = callback.GetNextValue();
  _upperLimit = (_lastSourceValue * IncrementSize) + 1;
}
return Make(_value++); //<--- New _upperLimit not used. We will get duplicate identities If another process called this

Should be something like:

else if (_upperLimit <= _value)
{
  _lastSourceValue = callback.GetNextValue();
  _upperLimit = (_lastSourceValue * IncrementSize) + 1;
  _value = _upperLimit - IncrementSize;
}
return Make(_value++);

Oskar Berggren added a comment — : Strange... Could you dig up a reference to the corresponding code in Hibernate please?


Tomas Gerhardsen added a comment — : The bug is found in Hibernate also: https://hibernate.atlassian.net/browse/HHH-3628

It is not fixed yet in the main branch: https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/id/enhanced/HiLoOptimizer.java#L80

hazzik commented 6 years ago

Fixed in Hibernate here:

  1. https://github.com/hibernate/hibernate-orm/commit/daa48b7db9bc8533a574d92fc2d6ea6fc6816702
  2. https://github.com/hibernate/hibernate-orm/commit/1aed1b50f7ecfa4129d47ddeb45a10207c2fd149
ZmorzynskiK commented 12 months ago

Hi,

I just stumbled upon this issue. I'm using the latest NHibernate (5.4.6) and got this violation when using HiLo optimizer. I'm wondering what's the suggested way of dealing with it? Should I just change to other optimizer like "pooled"? It looks like "pooled" updates _value before returning.