HTTP 响应后 DML 操作的解决方法
Workaround for DML Operation after HTTP Response
我需要发出一个 http 请求并在成功响应后创建并插入一条记录。这是代码片段
public static Collaboration__c createGroupCollaboration(Sub_Folder__C folder, String groupId, string role, String ProfId){
Box__c box = Box__c.getInstance();
HttpRequest req = new HttpRequest();
req.setEndpoint('https://test.api');
req.setMethod('POST');
req.setHeader('Authorization','Bearer '+box.BoxAccess_Token__c);
req.setBody('{"item": { "id": "'+folder.CF_box_folder_id__c+'", "type": "folder"}, "accessible_by": { "id": "'+groupId+'", "type": "group" }, "role": "'+role+'"}');
HTTPResponse res = new Http().send(req);
if(res.getStatuscode() >= 200 && res.getStatusCode() <= 299){
Collaborationwrapper cw = new Collaborationwrapper();
cw = (Collaborationwrapper)JSON.deserialize(res.getBody(),Collaborationwrapper.class);
Collaboration__c resCollab = new Collaboration__c(BoxCollaboration_Id__c = cw.Id,Role__c= cw.role,BoxFolder_Id__c= folder.CF_box_folder_id__c,Sub_folder__c= folder.id,BoxGroup_Id__c=groupId,SFUser_Email__c = 'group@test.com',SFProfile_Id__c = ProfId);
return resCollab;
}else {
return null;
}
}
这classreturns一个合作,将被插入。当我评论插入时,一切正常。但是,当我启用插入时,出现以下错误:您有未提交的工作挂起。调用前请提交或回滚。
我只需要在操作成功时插入这些记录。
我也需要为删除操作执行此操作,但我认为相同的方法将适用于这两个操作。
我知道你不应该在标注后执行 DML...但是我还能如何在成功响应时创建记录?
不,你有相反的方法。您可以先标注,再标注 DML。
你在顺丰做某事=你开始交易。它必须提交(成功)或回滚。如果您执行 DML - 您将锁定数据库。也许在单个记录上,也许在整个 table 上。然后你想做一个标注?在外部系统的摆布下,您最多可以将数据库扣为人质 2 分钟。 table 中的其他 DML 都不会成功。所以SF故意屏蔽了它。
但是先做 callout,再做 DML 是完全可以的。
你试过运行这个独立的吗?对于 1 条记录(文件或任何文件)。如果您遇到错误,您可能会在循环中调用它,然后第二次迭代会抛出错误。仔细查看调试日志。
或者也许在这段代码之前确实有一个插入,例如,如果你 运行 它关闭了触发器......在那种情况下你需要异步顶点(@future
,一个 Queueable
、批处理作业等)
我需要发出一个 http 请求并在成功响应后创建并插入一条记录。这是代码片段
public static Collaboration__c createGroupCollaboration(Sub_Folder__C folder, String groupId, string role, String ProfId){
Box__c box = Box__c.getInstance();
HttpRequest req = new HttpRequest();
req.setEndpoint('https://test.api');
req.setMethod('POST');
req.setHeader('Authorization','Bearer '+box.BoxAccess_Token__c);
req.setBody('{"item": { "id": "'+folder.CF_box_folder_id__c+'", "type": "folder"}, "accessible_by": { "id": "'+groupId+'", "type": "group" }, "role": "'+role+'"}');
HTTPResponse res = new Http().send(req);
if(res.getStatuscode() >= 200 && res.getStatusCode() <= 299){
Collaborationwrapper cw = new Collaborationwrapper();
cw = (Collaborationwrapper)JSON.deserialize(res.getBody(),Collaborationwrapper.class);
Collaboration__c resCollab = new Collaboration__c(BoxCollaboration_Id__c = cw.Id,Role__c= cw.role,BoxFolder_Id__c= folder.CF_box_folder_id__c,Sub_folder__c= folder.id,BoxGroup_Id__c=groupId,SFUser_Email__c = 'group@test.com',SFProfile_Id__c = ProfId);
return resCollab;
}else {
return null;
}
}
这classreturns一个合作,将被插入。当我评论插入时,一切正常。但是,当我启用插入时,出现以下错误:您有未提交的工作挂起。调用前请提交或回滚。
我只需要在操作成功时插入这些记录。
我也需要为删除操作执行此操作,但我认为相同的方法将适用于这两个操作。
我知道你不应该在标注后执行 DML...但是我还能如何在成功响应时创建记录?
不,你有相反的方法。您可以先标注,再标注 DML。
你在顺丰做某事=你开始交易。它必须提交(成功)或回滚。如果您执行 DML - 您将锁定数据库。也许在单个记录上,也许在整个 table 上。然后你想做一个标注?在外部系统的摆布下,您最多可以将数据库扣为人质 2 分钟。 table 中的其他 DML 都不会成功。所以SF故意屏蔽了它。
但是先做 callout,再做 DML 是完全可以的。
你试过运行这个独立的吗?对于 1 条记录(文件或任何文件)。如果您遇到错误,您可能会在循环中调用它,然后第二次迭代会抛出错误。仔细查看调试日志。
或者也许在这段代码之前确实有一个插入,例如,如果你 运行 它关闭了触发器......在那种情况下你需要异步顶点(@future
,一个 Queueable
、批处理作业等)