You need to sign in to do that
Don't have an account?
pedrosampaio
You have uncommitted work pending. Please commit or rollback before calling out
"(...) the only workaround is an ugly hack where you have to implement an Apex web service method that does the dml operations you wish to commit. Then invoke that web service method from within your Apex code that makes the HTTP callout."
Can anyone give some sample code on how to implement an Apex web service method that can be called from within your Apex code?
Thanks.
I have found a workaround to execute the webservice callout after inserting an object.
I execute an action to insert my object and then execute the webservice callout on the oncomplete event of a commandButton. Then, I return a PageReference giving the user immediate feedback.
If the webservice callout returns any error, I will delete object and returning the user back to the same page.
See bellow:
@VisualforcePage
...
<apex:actionFunction name="executeWS" action="{!executeWS}"></apex:actionFunction>
...
<apex:commandButton value="Save" action="{!save}" oncomplete="executeWS()" />
...
@Controller
public PageReference save() {
...
insert obj;
...
}
public PageReference executeWS(){
...
obj = [SELECT ...];
try{
callout ws;
} catch(System.Exception ex){
delete obj;
ApexPages.addMessages(e);
return null;
}
...
return new PageReference('/' + id);
}
Please, comment on this solution and what maybe the disadvantages of using it.
Note: using cookies to store obj id
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_sites_cookie.htm
All Answers
place @future annotation to the webservice method and try ....
Cannot do that because I need a response from the webservice to decide if I have to rollback the insert.
I'm not aware of any way to call a Salesforce webservice method from Apex code - I thought the platform stopped this.
You could call out to an external webservice that in turn executes a Salesforce web service, or you can invoke apex webservice methods from Javascript via the Ajax toolkit.
I recently encountered this problem. Basically you cant initiate DML Operations and then make a call out.
To get around this, invoke a future method, which does the web service call out for you, and then perform your DML operations after the callout has completed.
http://boards.developerforce.com/t5/Apex-Code-Development/You-have-uncommitted-work-pending-Please-commit-or-rollback/td-p/65803
eg :
@Future(callout=true)
public static void doRegister_Asynch(){
Account[] accts = [Select ....];
//Make webservice callout
for(Account acct : accts){
acc.Response_status__c = ....// set attributes to update
update accts;
}
I have found a workaround to execute the webservice callout after inserting an object.
I execute an action to insert my object and then execute the webservice callout on the oncomplete event of a commandButton. Then, I return a PageReference giving the user immediate feedback.
If the webservice callout returns any error, I will delete object and returning the user back to the same page.
See bellow:
@VisualforcePage
...
<apex:actionFunction name="executeWS" action="{!executeWS}"></apex:actionFunction>
...
<apex:commandButton value="Save" action="{!save}" oncomplete="executeWS()" />
...
@Controller
public PageReference save() {
...
insert obj;
...
}
public PageReference executeWS(){
...
obj = [SELECT ...];
try{
callout ws;
} catch(System.Exception ex){
delete obj;
ApexPages.addMessages(e);
return null;
}
...
return new PageReference('/' + id);
}
Please, comment on this solution and what maybe the disadvantages of using it.
Note: using cookies to store obj id
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_sites_cookie.htm