[ 
https://issues.apache.org/jira/browse/OFBIZ-2353?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14113937#comment-14113937
 ] 

Adrian Crum commented on OFBIZ-2353:
------------------------------------

Jacopo,

The main issue I see in the class is the handling of SequenceBank.curSeqId - 
there are too many places where access/modification is not synchronized.

There is a similar issue in the way the entity value is updated. The UPDATE... 
WHERE... statement needs to include the previous sequence value - so you can 
guarantee you are updating the same value you read.

Here is a workaround I use for my projects:

{code}
    public static String safeGetNextSeqId(Delegator delegator, String seqName) 
throws Exception {
        // OFBiz sequencer does not guarantee sequential IDs or unique IDs.
        javax.transaction.Transaction parentTx = TransactionUtil.suspend();
        try {
            long currentId = 10000;
            while (true) {
                TransactionUtil.begin();
                Map<String, Object> fieldMap = UtilMisc.toMap("seqName", 
seqName);
                GenericValue sequenceValue = 
delegator.findOne("SequenceValueItem", fieldMap, true);
                if (sequenceValue == null) {
                    sequenceValue = 
delegator.makeValidValue("SequenceValueItem", fieldMap);
                    sequenceValue.set("seqId", currentId); // OFBiz 
compatibility
                    sequenceValue.create();
                } else {
                    currentId = sequenceValue.getLong("seqId");
                    Map<String, Object> conditionMap = new HashMap<String, 
Object>(fieldMap);
                    conditionMap.put("seqId", currentId);
                    currentId++;
                    int updatedCount = 
delegator.storeByCondition("SequenceValueItem", UtilMisc.toMap("seqId", 
currentId),
                            EntityCondition.makeCondition(conditionMap));
                    if (updatedCount != 1) {
                        TransactionUtil.rollback();
                        continue;
                    }
                }
                TransactionUtil.commit();
                return String.valueOf(currentId);
            }
        } catch (Exception e) {
            try {
                TransactionUtil.rollback(e);
            } catch (Exception e2) {
                Debug.logError(e2, "Exception thrown while rolling back 
transaction", module);
            }
            throw e;

        } finally {
            TransactionUtil.resume(parentTx);
        }
    }
{code}


> SequenceUtil  may generate duplicate IDs in Load Balancing mode
> ---------------------------------------------------------------
>
>                 Key: OFBIZ-2353
>                 URL: https://issues.apache.org/jira/browse/OFBIZ-2353
>             Project: OFBiz
>          Issue Type: Bug
>          Components: framework
>    Affects Versions: Release Branch 4.0, Release Branch 09.04, Trunk
>            Reporter: Philippe Mouawad
>            Assignee: Jacopo Cappellato
>            Priority: Critical
>             Fix For: Release Branch 10.04, Release Branch 11.04, Trunk
>
>         Attachments: OFBIZ-2353 SELECT FOR UPDATE solution.patch, OFBIZ-2353 
> SELECT FOR UPDATE solution.patch
>
>
> If Ofbiz is deploy on 2 servers in Load Balancing Mode
> SequenceUtil will generate duplicate IDs because synchronization is done at 
> JVM level instead of doing it in DB.
> A good replacement implementation would be:
> org.hibernate.id.enhanced.TableGenerator
> But it would involve a dependency on Hibernate
> Philippe
> www.ubik-ingenierie.com



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to