如何在Salesforce Apex Class中手动创建新交易



我有一个每小时运行一次的调度进程,并调用另一个调用外部wsdl的类的方法。此方法用@Future进行注释(callout=true(当我从wsdl获取数据时,我会对其进行处理并将其插入salesforce对象中。由于数据非常巨大,我遇到了问题:DML语句太多:151

现在,我希望在不同的事务中处理每个响应记录,这样我就不会达到salesforce的限制。我试着用@future注释它,这样每次都会创建一个单独的事务。但现在我遇到了一个不同的问题,未来不能从未来中调用。

代码:预定课程:

class HourlySchedule implements Schedulable {
global void execute(SchedulableContext SC) {
Client.call();
}
}

类,该类对外部wsdl执行调用并获取响应:

class Client {
@future(callout = true) // this has to be there as Schedule class 
// cannot do a callout to external service
public static void call() {
// callout to wsdl 
// get response and process each client and its data
// here we can get 100's of client and each client can have 
ProcessClass.process();
}
}

处理数据的类

class ProcessClass {
public static void process(String data) {
// multiple insert statments
// cannot reduce them further as I have to insert the parent object first and then insert child object for creating master-detail relationship.
}
}

您可能在代码中有一个错误,不应该在循环中执行查询/插入/更新/删除。如果您正在解析该服务的响应并在SF中更新数据,请尝试将对象添加到列表中,并在主工作循环之外运行1次更新。如果没有看到你的代码,很难说更多。

如果你绝对需要">处理你能处理的,然后在下一个事务中提交下一块工作";。。。正如你所知道的,你得到了多少数据(来自该外部服务的X行(;天然的";进行批量作业。Batchable可以处理自定义迭代器,而不仅仅是从数据库中查询的行。这是一个不错的开始,但它没有显示start如何从外部服务获取数据,或者您甚至可以传递数据进行迭代。(没有什么能阻止你在这个类中创建一个带有对象列表的公共字段并传递它,然后假装你从start((返回了那个东西(

如果行数未知,您也可以查看Queueable。同样,假设您将1000条记录传递给它,每个Queueable execute((插入150条,并提交(入队(自己来处理下一个块。


编辑

不看数据很难,但我的建议是这样的。假设您有父节点,每个节点中都有一些唯一的标识符(甚至没有标识符(,每个节点都有子节点。这样做:

Map<String, Parent> parents = new Map<String, Parent>();
Map<String, List<Child>> childrenByParent = new Map<String, List<Child>>();
for(Parent p : yourDataParsedOrSomething){
parents.put(p.uniqueClientNumber, p);
List<Child> temp = new List<Child>();
for(Child ch : p.children){
temp.add(ch);
}
childrenByParent.put(p.uniqueClientNumber, temp);
}
insert parents.values();
List<Child> allChildren = new List<Child>();
for(String key : parents.keyset()){
Parent p = parents.get(key);
List<Child> children = childrenByParent.get(key);
for(Child ch : children){
ch.Parent__c = p.Id; // populate lookup
}
allChildren.addAll(children);
}
insert allChildren;

给你,两个插页。所有的父母,然后把ID映射回来,所有的孩子。即使您没有唯一的标识符,也可以完成类似的操作。这会有点混乱,但列表也算作索引,你可以有List<Parent>List<List<Child>>,你知道第七个父级的id必须设置在第七个子级列表上。。。

如果你有唯一的id,并在salesforce中将字段标记为外部id,这会变得更容易,你需要阅读外部id的upstart信息。https://stackoverflow.com/a/60024078/313628例如

最新更新