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