[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-3608) DB sequence numbers are not unique when using the pooled SequenceStyleGenerator in multiple JVMs with the same DB

Adrian Shum (JIRA) noreply at atlassian.com
Wed Nov 19 02:07:15 EST 2008


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-3608?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=31742#action_31742 ] 

Adrian Shum commented on HHH-3608:
----------------------------------

I have also hit exactly the same problem in my recent project (in fact I have just discovered it yesterday, I am coming to create issue for this but found an issue has just been created).

An extra supportive comment for Matthias' suggested change.

One of the reason that people choose SequenceStyleGenerator is to make ID generated synchronized with DB sequence value, and hence, we can create records directly (in DB, or thru JDBC etc) by using the sequence value as record's primary key.

However, current implementation still has chance for causing PK collision.

For example, in case of increment size of 10, my DB sequence is set with same increment size, and assume current value is 100
When I insert a record manually, its PK will be 100.  Next value of the sequence will be 110.

If now, Hibernate get the new "hiValue" from DB, "hiValue" will be 110, and "value" will be 110- 10 = 100, which will cause PK collision once Hibernate perform insert.

To make the change even cleaner, we can simply do
if ( hiValue < 0 || value >= hiValue) {
    value = callback.getNextValue();
    hiValue = value + incrementSize;
}

It will change the behavior of course.  A normal upgrade of hibernate won't have any problem. However, user should aware that if user fallback to a previous version, there may be chance that previous PK generated by later version of Hibernate may collide with new PK generated by former Hibnerate version


> DB sequence numbers are not unique when using the pooled SequenceStyleGenerator in multiple JVMs with the same DB
> -----------------------------------------------------------------------------------------------------------------
>
>                 Key: HHH-3608
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3608
>             Project: Hibernate Core
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 3.2.6, 3.3.0.GA, 3.3.0.SP1, 3.3.1
>         Environment: Hibernate 3.2.6, Oracle (any version)
>            Reporter: Matthias Gommeringer
>            Priority: Blocker
>         Attachments: PooledOptimizerTest.java
>
>
> 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.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list