Thanks for the reply Deepak. The ServiceUtil.isError() and isFailure() methods are in use by my services. I neglected to copy them over to my example. But what about unexpected exceptions like RuntimeException or something that is thrown by the service engine itself. I don't have a choice to return failure like I do in my own code but I still want my serviceB to commit?
Thanks, Matt Bertolini On 3/22/13 1:46 PM, "Deepak Dixit" <[email protected]> wrote: >Matt, > >As per you code if "doSomething" service return error then transaction >will be roll backed, as if service return error then transaction marked >as rollback hence it will rollback the transaction of parent service as >well. > >If doSomething fails to perform business logic then you can return >failure from service and then user ServiceUtil.isFailure() to check >failure and if this return true then you can run serviceB and return >error with errorMsg. > >So your code looks like this: > >{code} > try { > Map results = dispatcher.runSync("doSomething", data); // return >failure > if (ServiceUtil.isError(results)) { > // Service B requires a new transaction and should always > commit >regardless of outer transaction. > Map serviceBResults = dispatcher.runSync("serviceB", data); > return >ServiceUtil.returnError(ServiceUtil.getErrorMessage(results)) > } > } catch (GenericServiceException e) { > return ServiceUtil.returnError("message", e.getMessageList()); > } >{code} > >Or you can you use another syntax of runSync method for serviceB: > >{code} >try { > Map results = dispatcher.runSync("doSomething", data); > // Causes >error and initiates a rollback. > } catch (GenericServiceException e) { > // Service B requires a new transaction and should always commit >regardless of outer transaction. > Map serviceBResults = dispatcher.runSync("serviceB", data, 300, >true);// Use require new transaction true > return ServiceUtil.returnError("message", > e.getMessageList()); > } >{code} > > >Thanks & Regards >-- >Deepak Dixit >HotWax Media Pvt. Ltd. >www.hotwaxmedia.com >Contact :- +91-98267-54548 >Skype :- deepakdixit > >On Mar 22, 2013, at 8:02 PM, Matthew Bertolini wrote: > >> Sorry for the delayed response. I was swamped with other things. I have >> created a simplified example to demonstrate my code: >> >> // Outer transaction begins in serviceA >> public static Map serviceA(DispatchContext dispatchContext, Map >>inputData) >> { >> GenericDelegator delegator = dispatchContext.getDelegator(); >> LocalDispatcher dispatcher = dispatchContext.getDispatcher(); >> >> // ... >> >> try { >> Map results = dispatcher.runSync("doSomething", data); // Causes >> error and initiates a rollback. >> } catch (GenericServiceException e) { >> // Service B requires a new transaction and should always commit >> regardless of outer transaction. >> Map serviceBResults = dispatcher.runSync("serviceB", data); >> return ServiceUtil.returnError("message", e.getMessageList()); >> } >> >> // ... >> >> return ServiceUtil.returnSuccess(successMessage); >> } >> >> >> I hope this helps illustrate the issue. >> >> Thanks >> Matt Bertolini >> >> On 3/14/13 11:01 AM, "Nicolas Malin" <[email protected]> >>wrote: >> >>> Matt can you give me the serviceA code ? >>> >>> Nicolas >>> >>> Le 14/03/2013 15:53, Matthew Bertolini a écrit : >>>> ServiceA has errored and therefore a rollback has been initiated >>>>before >>>> serviceB has been called but execution of serviceA has not yet >>>> completed. >>>> I am not sure what you mean by iterating. Also, I am working in pure >>>> java >>>> so any minilang solutions will not apply. >>>> >>>> Thanks, >>>> Matt Bertolini >>>> >>>> On 3/13/13 4:12 PM, "Nicolas Malin" <[email protected]> >>>> wrote: >>>> >>>>> Hi Matt, >>>>> >>>>> If the service A has been rollbacked before call the serviceB ? >>>>> If you call serviceB on new transaction, the serviceA wait the >>>>>serviceB >>>>> return so this last has been commited. >>>>> >>>>> Warn with log if you work with a loop : >>>>> Service A : >>>>> <iterate ..> >>>>> <call-service name="serviceB"/> >>>>> </> >>>>> >>>>> Nicolas >>>>> >>>>> >>>>> >>>>> Le 13/03/2013 20:33, Matthew Bertolini a écrit : >>>>>> I have two service engine methods in Java. Lets call them serviceA >>>>>>and >>>>>> serviceB. ServiceA calls serviceB. Both are transactional but >>>>>>serviceB >>>>>> requires a new transaction. The reason is I want serviceB to succeed >>>>>> even if serviceA needs to rollback (serviceB is a db audit logging >>>>>> method). In this setup, I get the following message when serviceA >>>>>> errors: >>>>>> >>>>>> The current transaction is marked for rollback, not beginning a new >>>>>> transaction and aborting current operation; the rollbackOnly was >>>>>> caused >>>>>> by: Service [serviceA] Š >>>>>> >>>>>> Based on analysis of the database, I can see that serviceA did >>>>>> rollback >>>>>> as expected but serviceB didn't commit either. Not really sure how >>>>>>to >>>>>> fix this particular issue. Does "require-new-transaction" not really >>>>>> work as advertised? What am I missing? >>>>>> >>>>>> Thanks, >>>>>> Matt Bertolini >>>>>> >>>>> >>>>> -- >>>>> Nicolas MALIN >>>>> Consultant >>>>> Tél : 06.17.66.40.06 >>>>> Site projet : http://www.neogia.org/ >>>>> ------- >>>>> Société LibrenBerry >>>>> Tél : 02.48.02.56.12 >>>>> Site : http://www.librenberry.net/ >>>>> >>> >>> >>> -- >>> Nicolas MALIN >>> Consultant >>> Tél : 06.17.66.40.06 >>> Site projet : http://www.neogia.org/ >>> ------- >>> Société LibrenBerry >>> Tél : 02.48.02.56.12 >>> Site : http://www.librenberry.net/ >>> >> >
