[
https://issues.apache.org/jira/browse/OFBIZ-3557?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13447316#comment-13447316
]
Markus M. May commented on OFBIZ-3557:
--------------------------------------
We have now implemented the Service "invoiceSequenceEnforced" with a small
Java-Method, so that the Transaction starts in the method and ends after
committing the change on the DB. Seems to work now ;-)
{code:title=InvoiceServices.java|borderStyle=solid}
// service to create a new invoiceId in a small transaction, so that the ids
are updated correctly
public static Map<String, Object> invoiceSequenceEnforced(DispatchContext
dctx, Map<String, Object> context) throws GenericServiceException {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
Locale locale = (Locale) context.get("locale");
String partyId = (String) context.get("partyId");
Transaction parentTransaction = null;
Long lastInvoiceNumber = null;
try {
// Enforce a new Transaction
parentTransaction = TransactionUtil.suspend();
if (TransactionUtil.isTransactionInPlace()) {
throw new GenericTransactionException("In service " + module + "
transaction is still in place after suspend, status is " +
TransactionUtil.getStatusString());
}
// now start a new transaction
boolean beganTrans = TransactionUtil.begin(0);
GenericValue partyAcctgPreference =
delegator.findOne("PartyAcctgPreference", false, UtilMisc.toMap("partyId",
partyId));
lastInvoiceNumber = partyAcctgPreference.getLong("lastInvoiceNumber");
if (UtilValidate.isNotEmpty(lastInvoiceNumber)) {
lastInvoiceNumber = lastInvoiceNumber + 1L;
} else {
lastInvoiceNumber = 1L;
}
Debug.logInfo("generated new InvoiceNumber: " + lastInvoiceNumber,
module);
partyAcctgPreference.set("lastInvoiceNumber", lastInvoiceNumber);
partyAcctgPreference.store();
TransactionUtil.commit();
} catch (GenericEntityException e) {
Debug.logError (e, "Entity/data problem creating invoiceId: " +
e.toString(), module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"AccountingEntityDataProblemCreatingInvoiceFromOrderItems",
UtilMisc.toMap("reason", e.toString()), locale));
} finally {
// resume the parent transaction
if (parentTransaction != null) {
try {
TransactionUtil.resume(parentTransaction);
} catch (GenericTransactionException ite) {
Debug.logWarning(ite, "Transaction error, not resumed", module);
throw new GenericServiceException("Resume transaction exception, see
logs");
}
}
}
Map<String, Object> result = ServiceUtil.returnSuccess();
result.put("invoiceId", lastInvoiceNumber);
return result;
}
{code}
And in the service-defition:
{code title=sales_invoice.xml|borderStyle=solid}
<service name="invoiceSequence-enforced" engine="java"
location="org.ofbiz.accounting.invoice.InvoiceServices"
invoke="invoiceSequenceEnforced">
<attribute name="partyAcctgPreference"
type="org.ofbiz.entity.GenericValue" mode="IN"/>
<attribute name="partyId" type="String" mode="IN" optional="false"/>
<attribute name="invoiceId" type="Long" mode="OUT"/>
</service>
{code}
Up until now, this seems to work fine. It still has the above mentioned
problem, that a sequence number is wasted if an invoice creation is rolled
back, though. Therefor this issue is still marked as open, this is just a minor
workaround.
> Enforced sequence does not work with concurrent access
> ------------------------------------------------------
>
> Key: OFBIZ-3557
> URL: https://issues.apache.org/jira/browse/OFBIZ-3557
> Project: OFBiz
> Issue Type: Bug
> Components: framework
> Affects Versions: Release Branch 09.04, SVN trunk
> Reporter: Wickersheimer Jeremy
> Attachments: OFBIZ-3557-1.patch, OFBIZ-3557-2.patch
>
>
> There is a fundamental issue with enforced sequences (for orders, invoices,
> etc ..) and concurrency.
> For example if two users are creating an order at the same time one of them
> will see the creation fail with a PK error. The problem is that the
> "getNextXXXId" rely on the party accounting preference entity, but there is
> absolutely no guarantee that the last number in the sequence gets updated
> before another service can read it.
> This is at best very annoying when used only internally but may be
> unpractical for e-commerce sites.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira