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
>
>
>

Reply via email to