You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ofbiz.apache.org by "Adrian Crum (JIRA)" <ji...@apache.org> on 2014/08/28 18:38:08 UTC
[jira] [Commented] (OFBIZ-2353) SequenceUtil may generate
duplicate IDs in Load Balancing mode
[ 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)