openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Milosz Tylenda (JIRA)" <j...@apache.org>
Subject [jira] Reopened: (OPENJPA-466) Primary key constraint violated using (Oracle) sequence to generate ID in multithreaded app
Date Mon, 30 Mar 2009 17:50:50 GMT

     [ https://issues.apache.org/jira/browse/OPENJPA-466?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Milosz Tylenda reopened OPENJPA-466:
------------------------------------


Although the patch applied (synchronization on PreparedStatement within NativeJDBCSeq.getSequence)
does a good job on reducing the likelihood of crash, I am afraid we are still not free from
multi-threading issue. On my one-core laptop I am not able to reproduce this issue (even when
I remove the patch) but I find the problem still exists in the AbstractJDBCSeq.next method.
I am able to reproduce the exception when I insert Thread.yield():

    public Object next(StoreContext ctx, ClassMetaData meta) {
        JDBCStore store = getStore(ctx);
        try {
            current = nextInternal(store, (ClassMapping) meta);
            Thread.yield();
            return current;
        } catch (OpenJPAException ke) {
            throw ke;
        } catch (SQLException se) {
            throw SQLExceptions.getStore(se, store.getDBDictionary());
        } catch (Exception e) {
            throw new StoreException(e);
        }
    }

This yield() simulates context switching in an real application. The context switch will actually
seldom occur here but is possible to my knowledge. Also, I am able to reproduce the exception
by adding some Thread.sleep calls instead of yield() but this is harder to reproduce.

My suggestion is to remove the synchronization from NativeJDBCSeq.getSequence and modify AbstractJDBCSeq.next
to something like the following:

    public Object next(StoreContext ctx, ClassMetaData meta) {
        JDBCStore store = getStore(ctx);
        try {
                Object currentLocal = nextInternal(store, (ClassMapping) meta);
                current = currentLocal;
                return currentLocal;
        } catch (OpenJPAException ke) {
            throw ke;
        } catch (SQLException se) {
            throw SQLExceptions.getStore(se, store.getDBDictionary());
        } catch (Exception e) {
            throw new StoreException(e);
        }
    }


> Primary key constraint violated using (Oracle) sequence to generate ID in multithreaded
app
> -------------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-466
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-466
>             Project: OpenJPA
>          Issue Type: Bug
>    Affects Versions: 1.0.0, 1.0.1, 1.1.0, 1.2.0
>         Environment: OpenJPA 1.0.0 (also tried 1.0.1 and 1.1.0-SNAPSHOT)
> Oracle XE 10g (JDBC driver 10.2.0.3.0)
> Windows XP Pro
>            Reporter: Frank Le
>            Assignee: Tim McConnell
>            Priority: Blocker
>             Fix For: 2.0.0
>
>         Attachments: OPENJPA-466.patch
>
>
> Here's how I annotate the ID:
>     @Id
>     @SequenceGenerator(name = "FooSeq", sequenceName = "seq_foo", allocationSize = 20)
>     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "FooSeq")
>     private Long id;
> Here's how I create the (Oracle) sequence:
> CREATE SEQUENCE seq_foo START WITH 1 INCREMENT BY 1;
> I get a primary key unique constraint violated in a multithreaded app i.e. it doesn't
happen in single-threaded!
> You can simply reproduce this error by either create blocking queue or blocking thread
pool say size 5 to insert 10000+ object.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message