if your not losing data in the database, or your not seeing errors about transactions aborted. it is probably not a bug. the way to verify this is to watch what a transaction does and then see if it is put in the db. if you can verify that the data in not being put in the db and can give the steps to reproduce this, then others can take a look. :D
Jack Liu sent the following on 4/19/2009 8:41 PM: > Yes, I know. > But I am not sure if this is a bug or not because there are no documents to > describe how to use local transaction or global transaction in OFBiz. > > -----Original Message----- > From: BJ Freeman [mailto:[email protected]] > Sent: 2009年4月20日 11:35 > To: [email protected] > Subject: Re: transaction consistency in ofbiz > > This is a community driven project > the people here, are volunteers. > so unless someone is interested in your problem, it will be you that > comes up with a fix. > if you have a bug, then put in a jira. > http://docs.ofbiz.org/display/OFBADMIN/OFBiz+Contributors+Best+Practices > > Jack Liu sent the following on 4/19/2009 7:50 PM: >> The problem has bothered me for several days. >> Who can help me? >> Thank you. >> >> -----Original Message----- >> From: Jack Liu [mailto:[email protected]] >> Sent: 2009年4月19日 19:36 >> To: [email protected] >> Subject: RE: transaction consistency in ofbiz >> >> I am still using service engine's transaction. >> <service name="processCustomerApprove" engine="java" location="task.Task" >> invoke="processCustomerApprove"> >> <attribute name="wfid" mode="IN" type="Long" >> optional="false" /> >> <attribute name="action" mode="IN" type="String" >> optional="true" /> >> <attribute name="conclusion" mode="IN" type="String" >> optional="false" /> >> <attribute name="opinion" mode="IN" type="String" >> optional="true" /> >> </service> >> Attribute use-transaction is set default to be true, which is defined in >> Services.xsd >> In task.Task.java, if the method shows like below,then transaction fails >> >> public static Map processCustomerApprove(DispatchContext dctx, Map context) { >> Map result = ServiceUtil.returnSuccess(); >> GenericDelegator delegator = dctx.getDelegator(); >> try { >> String opinion = (String) context.get("opinion"); >> String conclusion = (String) context.get("conclusion"); >> Debug.logInfo("Conclusion=" + conclusion + "\nopinion=" >> + opinion, >> module); >> >> Long id = new Long(delegator.getNextSeqId("Opinion")); >> Debug.logInfo("id = " + id, module); >> GenericValue opinionValue = >> delegator.makeValue("Opinion", UtilMisc >> .toMap("id", id)); >> opinionValue.set("wfid", wfid); >> opinionValue.set("approver", UserUtil.getUserName()); >> opinionValue.set("conclusion", conclusion); >> opinionValue.set("opinion", opinion); >> delegator.create(opinionValue); >> >> Map test = new HashMap(); >> Test.put("kid",new Long(111)); >> Long customerid = CcbUtils.getNextSeqId(delegator, >> "customerinfo"); >> GenericValue customerInfo = >> delegator.makeValue("Customerinfo", >> UtilMisc.toMap("id", id)); >> customerInfo.setFields(); >> delegator.create(customerInfo); >> return result; >> }catch (GenericEntityException e) { >> e.printStackTrace(); >> return ServiceUtil.returnError(e.getMessage()); >> } >> >> So how is service engine's transaction used? >> But If I add TransactionUtil.begin(),commit() and rollback() in the above >> method, then transaction works. >> This is not the end. When I add some more code to invoke OSWorkflow which >> uses another datasource also configured in entityengine.xml and use the same >> instance of GenericDelegator, transaction fails again........ >> So my question is how I should do to implement transaction consistency in >> OFBiz when processing multiple datasources. >> >> Thank you in advance. >> >> -----Original Message----- >> From: David E Jones [mailto:[email protected]] >> Sent: 2009年4月18日 2:25 >> To: [email protected] >> Subject: Re: transaction consistency in ofbiz >> >> >> It sounds like you're digging pretty deep, and I'd recommend a peek at >> the TransactionUtil.java file. It's really quite simple code. >> >> The begin() method returns false if there is already a transaction in >> place, and along with it the rollback(beganTransaction) method will >> only do the actually rollback if beganTransaction is true, otherwise >> it will set the rollbackOnly flag. Why does it do this? The basic idea >> is that a code block should never commit or rollback a transaction it >> didn't begin (ie that's a fundamental rule for transaction management >> code). >> >> I HIGHLY recommend you find a good book on transaction management >> because there are lots of things you need to know about to write >> proper transaction demarcation code, either that or use the Service >> Engine's transaction handling features (that's what they are there >> for...). >> >> -David >> >> >> On Apr 17, 2009, at 4:27 AM, Jack Liu wrote: >> >>> I want to know Why TransactionUtil.begin() return false not true. >>> It doesn't support transaction? >>> >>> -----Original Message----- >>> From: Jack Liu [mailto:[email protected]] >>> Sent: 2009年4月17日 16:42 >>> To: [email protected] >>> Subject: RE: transaction consistency in ofbiz >>> >>> Yes,I am sure because I debug step by step. >>> >>> GenericEntity.set() throws IllegalArgumentException ; >>> >>> I use OFBiz trunk version >>> >>> ________________________________ >>> >>> From: Scott Gray [mailto:[email protected]] >>> Sent: 2009年4月17日 16:28 >>> To: [email protected] >>> Subject: Re: transaction consistency in ofbiz >>> >>> >>> >>> Are you sure that a transaction rollback is actually invoked? >>> GenericEntity.setFields() calls GenericEntity.set() which has a >>> statement in it that logs an exception but doesn't actually throw one. >>> >>> >>> >>> Regards >>> >>> Scott >>> >>> >>> >>> HotWax Media >>> >>> http://www.hotwaxmedia.com <http://www.hotwaxmedia.com/> >>> >>> >>> >>> On 17/04/2009, at 7:41 PM, Jack Liu wrote: >>> >>> >>> >>> >>> >>> Hi, All >>> In OFBiz, there is a class named TransactionUtil which helps with some >>> common transaction tasks >>> I want to know how to use it, so I wrote some code below >>> >>> public static Map processCustomerApprove(DispatchContext dctx, Map >>> context) { >>> Map result = ServiceUtil.returnSuccess(); >>> GenericDelegator delegator = dctx.getDelegator(); >>> >>> boolean beganTransaction = false; >>> try { >>> beganTransaction = TransactionUtil.begin(); >>> >>> Workflow workflow = >>> WorkFlowFactory.getWorkFlow(UserUtil >>> .getUserName()); >>> Long wfid = (Long) context.get("wfid"); >>> int actionNum = Integer.parseInt((String) >>> context.get("action")); >>> Debug.logInfo("workflow=" + wfid + >>> ",actionnumber=" + actionNum, >>> module); >>> >>> String opinion = (String) >>> context.get("opinion"); >>> String conclusion = (String) >>> context.get("conclusion"); >>> Debug.logInfo("Conclusion=" + conclusion + >>> "\nopinion=" + opinion, >>> module); >>> >>> Long id = new >>> Long(delegator.getNextSeqId("Opinion")); >>> Debug.logInfo("id = " + id, module); >>> GenericValue opinionValue = >>> delegator.makeValue("Opinion", UtilMisc >>> .toMap("id", id)); >>> opinionValue.set("wfid", wfid); >>> opinionValue.set("approver", >>> UserUtil.getUserName()); >>> opinionValue.set("conclusion", conclusion); >>> opinionValue.set("opinion", opinion); >>> delegator.create(opinionValue); >>> >>> Map inputs = new HashMap(); >>> inputs.put("conclusion", conclusion); >>> workflow.doAction(wfid, actionNum, inputs); >>> Debug.logInfo("workflow enters next step", >>> module); >>> >>> >>> if ("Agree".equals(conclusion) && actionNum == >>> 2) { >>> // >>> EntityCondition wfidCondition = >>> EntityCondition.makeCondition( >>> "wfid", >>> EntityOperator.EQUALS, wfid); >>> List customerInfoHistoryList = >>> delegator.findList( >>> "CustomerinfoHistory", >>> wfidCondition, null, UtilMisc >>> >>> .toList("id DESC"), null, false); >>> GenericValue value = >>> EntityUtil.getFirst(customerInfoHistoryList); >>> //copy customer info from table >>> customerinfohistory to customerinfo >>> //value.remove("wfid"); >>> value.remove("id"); >>> >>> Long customerid = >>> CcbUtils.getNextSeqId(delegator, "customerinfo"); >>> Debug.logInfo("id = " + customerid, >>> module); >>> GenericValue customerInfo = >>> delegator.makeValue("Customerinfo", >>> UtilMisc.toMap("id", >>> id)); >>> customerInfo.setFields(value); >>> delegator.create(customerInfo); >>> >>> } >>> >>> } catch (Exception e) { >>> try { >>> >>> TransactionUtil.rollback(beganTransaction, "something wrong in the >>> operation", e); >>> } catch (GenericTransactionException e1) { >>> e1.printStackTrace(); >>> } >>> }finally { >>> try { >>> TransactionUtil.commit(); >>> } catch (GenericTransactionException e) { >>> e.printStackTrace(); >>> } >>> } >>> >>> return result; >>> } >>> } >>> >>> When I debug, TransactionUtil.begin() returns false, >>> And an error happens when running customerInfo.setFields(value) (I >>> know >>> why), >>> , so jvm catches the exception, TransactionUtil.rollback is invoked. >>> Because beganTransaction is false, it doesn't roll back. >>> When program ends, transaction doesn't work eventually. >>> >>> Could you tell me how I should do to keep transaction consistent? >>> >>> >>> >>> >>> Best Regards, >>> >>> Jack Liu >>> >>> >>> >> >> > >
