Salesforce @future(callout=true) 方法永远不会 运行
Salesforce @future(callout=true) method is never run
我正在尝试从 salesforce 调用大部分代码是从另一个工作包复制的。
谁能告诉我为什么下面的 call out 方法永远不会 运行?
我在调用调用方法之前和之后保存到我的自定义 table 中,但是保存到我的自定义 table 中的调用没有在调用方法中调用。
public class AutoSyncConnector {
public AutoSyncConnector()
{
}
public void Fire(string jsonToPost)
{
// 1. Authentication send the current session id so that request can be validated
String sessionId = UserInfo.getSessionId();
// 2. warp the request and post it to the configured end point
// This is how to get settings out for custom settings list
String connectorUrl = ASEndPoints__c.getValues('MainUrlEndPoint').autosync__MainSiteUrl__c;
CastlesMessageLog__c cd = new CastlesMessageLog__c();
cd.SentJson__c = 'before call out this is called';
insert cd;
AutoSyncConnector.CallOut(jsonToPost, connectorUrl);
CastlesMessageLog__c cd2 = new CastlesMessageLog__c();
cd2.SentJson__c = 'after call out this is called';
insert cd2;
}
public static void CallOut(String jsonToPost, String connectorUrl)
{
MakeCallout(jsonToPost,connectorUrl);
}
@future(callout=true)
public static void MakeCallout(String jsonToPost, String connectorUrl){
CastlesMessageLog__c cd = new CastlesMessageLog__c();
cd.SentJson__c = 'start inside before call out this is never called';
insert cd;
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setTimeout(120000);
// string authorizationHeader = 'Check I can add stuff to the header';
String sfdcConnectorUrl = connectorUrl + '/api/autosyncwebhook';
req.setEndpoint(sfdcConnectorUrl);
//req.setHeader('Authorization', authorizationHeader);
req.setMethod('POST');
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
req.setBody(jsonToPost);
h.send(req);
CastlesMessageLog__c cd2 = new CastlesMessageLog__c();
cd2.SentJson__c = 'end inside before call out this is never called';
insert cd2;
}
}
转到设置 -> 监控 -> Apex 作业。我的直觉是你会看到很多 "uncommitted work pending" 错误。
当您创建任何 DML (insert/update/delete) 时,您会打开一个与数据库的事务。如果您接下来要做的是标注(最大超时时间可以为 120 秒),则意味着您将锁定此记录(甚至整个 table)很长时间。 SF 无法知道调用是否会成功或必须回滚。所以他们通过立即禁止此类代码来保护这种情况 ;)
先标注,再标注 DML。
或者制作 DML,调用 @future(这就是目的,切换到另一个线程,分离上下文),如果标注返回错误 - 做任何你认为回滚的清理(删除记录?将其更新为状态 = 同步失败?向用户发送电子邮件/为他插入任务以稍后重试?)
我正在尝试从 salesforce 调用大部分代码是从另一个工作包复制的。
谁能告诉我为什么下面的 call out 方法永远不会 运行?
我在调用调用方法之前和之后保存到我的自定义 table 中,但是保存到我的自定义 table 中的调用没有在调用方法中调用。
public class AutoSyncConnector {
public AutoSyncConnector()
{
}
public void Fire(string jsonToPost)
{
// 1. Authentication send the current session id so that request can be validated
String sessionId = UserInfo.getSessionId();
// 2. warp the request and post it to the configured end point
// This is how to get settings out for custom settings list
String connectorUrl = ASEndPoints__c.getValues('MainUrlEndPoint').autosync__MainSiteUrl__c;
CastlesMessageLog__c cd = new CastlesMessageLog__c();
cd.SentJson__c = 'before call out this is called';
insert cd;
AutoSyncConnector.CallOut(jsonToPost, connectorUrl);
CastlesMessageLog__c cd2 = new CastlesMessageLog__c();
cd2.SentJson__c = 'after call out this is called';
insert cd2;
}
public static void CallOut(String jsonToPost, String connectorUrl)
{
MakeCallout(jsonToPost,connectorUrl);
}
@future(callout=true)
public static void MakeCallout(String jsonToPost, String connectorUrl){
CastlesMessageLog__c cd = new CastlesMessageLog__c();
cd.SentJson__c = 'start inside before call out this is never called';
insert cd;
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setTimeout(120000);
// string authorizationHeader = 'Check I can add stuff to the header';
String sfdcConnectorUrl = connectorUrl + '/api/autosyncwebhook';
req.setEndpoint(sfdcConnectorUrl);
//req.setHeader('Authorization', authorizationHeader);
req.setMethod('POST');
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
req.setBody(jsonToPost);
h.send(req);
CastlesMessageLog__c cd2 = new CastlesMessageLog__c();
cd2.SentJson__c = 'end inside before call out this is never called';
insert cd2;
}
}
转到设置 -> 监控 -> Apex 作业。我的直觉是你会看到很多 "uncommitted work pending" 错误。
当您创建任何 DML (insert/update/delete) 时,您会打开一个与数据库的事务。如果您接下来要做的是标注(最大超时时间可以为 120 秒),则意味着您将锁定此记录(甚至整个 table)很长时间。 SF 无法知道调用是否会成功或必须回滚。所以他们通过立即禁止此类代码来保护这种情况 ;)
先标注,再标注 DML。
或者制作 DML,调用 @future(这就是目的,切换到另一个线程,分离上下文),如果标注返回错误 - 做任何你认为回滚的清理(删除记录?将其更新为状态 = 同步失败?向用户发送电子邮件/为他插入任务以稍后重试?)