Uploaded image for project: 'Hibernate ORM'
  1. HHH-3608

DB sequence numbers are not unique when using the pooled SequenceStyleGenerator in multiple JVMs with the same DB

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Duplicate
    • Affects Version/s: 3.2.6, 3.3.0.GA, 3.3.0.SP1, 3.3.1
    • Fix Version/s: None
    • Component/s: hibernate-core
    • Labels:
      None
    • Environment:
      Hibernate 3.2.6, Oracle (any version)
    • Bug Testcase Reminder (view):

      Bug reports should generally be accompanied by a test case!

    • Last commented by a user?:
      true

      Description

      We have several Application Servers (=JVMs) running each of them using Hibernate-Objects with the SequenceStyleGenerator+pooled configured. In unpredictable time intervals it happens that hibernate assigns the same ID to two completely different objects which results in a UniqueConstraintViolation exception from the database. Here an example with a description where hibernate fails:

      DB-Sequence setup:
      start=0
      increment=2

      PooledOptimizer.generate() with 2 threads (first assignment of hiValue/value):
      JVM-1 JVM-2
      value=0=callback.nextval
      value=2=callback.nextval
      hiValue=4=callback.nextval
      hiValue=6=callback.nextval

      The problem's cause is in the PooledOptimizer.generate: when it initializes
      the value+hiValue for the first time it invokes callback.nextValue() twice which
      may provide values that do not belong to each other. The reason is that
      between the assignment of "value" and "hiValue" another JVM can retrieve a
      DB sequence value from the callback which leads to an inconsistent "value" and "hiValue"
      relation (see example above).

      A fix that works for multiple JVMs would be to invoke the "callback.getNextValue()" maximum once
      per "optimizer.generate()" call:

      public synchronized Serializable generate(AccessCallback callback) {
      if ( hiValue < 0 )

      { value = callback.getNextValue(); hiValue = value + incrementSize; }
      else if ( value >= hiValue ) { value = callback.getNextValue(); hiValue = value + incrementSize; }

      return make(value++);
      }

      I attached a testcase that prooves the described problem (you can see that the IDs "2" and "3" are assigned two times).

      I would be very thankful if this problem could be fixed very soon since it is a showstopper which
      occurs very unpredictably.

        Attachments

          Issue links

            Activity

              People

              • Votes:
                18 Vote for this issue
                Watchers:
                16 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 2h
                  2h