transaction consistency in ofbiz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

transaction consistency in ofbiz

Jack Liu-2
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 | Threaded
Open this post in threaded view
|

Re: transaction consistency in ofbiz

Scott Gray-2
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


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



smime.p7s (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

RE: transaction consistency in ofbiz

Jack Liu-2
Yes,I am sure because I debug step by step.

GenericEntity.set() throws IllegalArgumentException ;

I use OFBiz trunk version

________________________________

From: Scott Gray [mailto:[hidden email]]
Sent: 2009年4月17日 16:28
To: [hidden email]
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 | Threaded
Open this post in threaded view
|

FW: transaction consistency in ofbiz

Jack Liu-2
In reply to this post by Jack Liu-2
I want to know Why TransactionUtil.begin() return false not true.
It doesn't support transaction?

-----Original Message-----
From: Jack Liu [mailto:[hidden email]]
Sent: 2009年4月17日 16:42
To: [hidden email]
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:[hidden email]]
Sent: 2009年4月17日 16:28
To: [hidden email]
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 | Threaded
Open this post in threaded view
|

Re: transaction consistency in ofbiz

David E Jones-3

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:[hidden email]]
> Sent: 2009年4月17日 16:42
> To: [hidden email]
> 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:[hidden email]]
> Sent: 2009年4月17日 16:28
> To: [hidden email]
> 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 | Threaded
Open this post in threaded view
|

RE: transaction consistency in ofbiz

Jack Liu-2
Thank you for your response.
Yes, you are totally right, I know little JTA and transaction management.
To my question, the begin() method returns false so rollback(false) will not rollback transaction but set rollbackOnly flag. Since rollbackOnly is set, the current thread's transaction will be rolled back at last. Am I right?

-----Original Message-----
From: David E Jones [mailto:[hidden email]]
Sent: 2009年4月18日 2:25
To: [hidden email]
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:[hidden email]]
> Sent: 2009年4月17日 16:42
> To: [hidden email]
> 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:[hidden email]]
> Sent: 2009年4月17日 16:28
> To: [hidden email]
> 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 | Threaded
Open this post in threaded view
|

RE: transaction consistency in ofbiz

Jack Liu-2
In reply to this post by David E Jones-3
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:[hidden email]]
Sent: 2009年4月18日 2:25
To: [hidden email]
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:[hidden email]]
> Sent: 2009年4月17日 16:42
> To: [hidden email]
> 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:[hidden email]]
> Sent: 2009年4月17日 16:28
> To: [hidden email]
> 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 | Threaded
Open this post in threaded view
|

RE: transaction consistency in ofbiz

Jack Liu-2
The problem has bothered me for several days.
Who can help me?
Thank you.

-----Original Message-----
From: Jack Liu [mailto:[hidden email]]
Sent: 2009年4月19日 19:36
To: [hidden email]
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:[hidden email]]
Sent: 2009年4月18日 2:25
To: [hidden email]
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:[hidden email]]
> Sent: 2009年4月17日 16:42
> To: [hidden email]
> 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:[hidden email]]
> Sent: 2009年4月17日 16:28
> To: [hidden email]
> 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 | Threaded
Open this post in threaded view
|

Re: transaction consistency in ofbiz

BJ Freeman
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:[hidden email]]
> Sent: 2009年4月19日 19:36
> To: [hidden email]
> 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:[hidden email]]
> Sent: 2009年4月18日 2:25
> To: [hidden email]
> 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:[hidden email]]
>> Sent: 2009年4月17日 16:42
>> To: [hidden email]
>> 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:[hidden email]]
>> Sent: 2009年4月17日 16:28
>> To: [hidden email]
>> 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 | Threaded
Open this post in threaded view
|

RE: transaction consistency in ofbiz

Jack Liu-2
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:[hidden email]]
Sent: 2009年4月20日 11:35
To: [hidden email]
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:[hidden email]]
> Sent: 2009年4月19日 19:36
> To: [hidden email]
> 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:[hidden email]]
> Sent: 2009年4月18日 2:25
> To: [hidden email]
> 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:[hidden email]]
>> Sent: 2009年4月17日 16:42
>> To: [hidden email]
>> 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:[hidden email]]
>> Sent: 2009年4月17日 16:28
>> To: [hidden email]
>> 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 | Threaded
Open this post in threaded view
|

Re: transaction consistency in ofbiz

BJ Freeman
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:[hidden email]]
> Sent: 2009年4月20日 11:35
> To: [hidden email]
> 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:[hidden email]]
>> Sent: 2009年4月19日 19:36
>> To: [hidden email]
>> 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:[hidden email]]
>> Sent: 2009年4月18日 2:25
>> To: [hidden email]
>> 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:[hidden email]]
>>> Sent: 2009年4月17日 16:42
>>> To: [hidden email]
>>> 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:[hidden email]]
>>> Sent: 2009年4月17日 16:28
>>> To: [hidden email]
>>> 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
>>>
>>>
>>>
>>
>>
>
>