我正在尝试编写一个“更新后”触发器,它对刚刚更新的记录的所有子记录执行批量更新。这需要能够一次处理15k +子记录。不幸的是,限制似乎是100,这远远低于我的需求它甚至不接受。我没有尝试将记录分成每批100个,因为这仍然会使每个触发器执行的上限达到10k。 (也许我可以将菊花链连接在一起?呃。)
有谁知道我可以通过什么系列的箍来克服这个限制?
编辑:我尝试在触发器中调用@future函数,但它从不更新子记录:
global class ParentChildBulkUpdater
{
@future
public static void UpdateChildDistributors(String parentId) {
Account[] children = [SELECT Id FROM Account WHERE ParentId = :parentId];
for(Account child : children)
child.Site = 'Bulk Updater Fired';
update children;
}
}
答案 0 :(得分:4)
解决此问题的最佳(也是最简单)路线是使用Batch Apex,您可以创建批次类并从触发器中触发它。像@future一样,它在一个单独的线程中运行,但它可以处理多达50,000,000条记录!
在使用database.executeBatch
之前,您需要将一些信息传递给您的批次类,以便它具有要使用的父ID列表,或者您当然可以获得所有帐户;)
我只是注意到这个问题有多久了,但希望这个答案可以帮助其他人。
答案 1 :(得分:2)
最糟糕的是,你甚至无法在第一时间获得这些15k记录,因为触发器中有1000行查询限制(这会扩展到触发器的行数)要求,但这可能没有帮助)
我想你唯一的方法就是使用@future标签 - 在文档中阅读。它为您提供了更高的限制。虽然,你只能在一天内调用那么多 - 所以你可能需要以某种方式跟踪哪些父对象让他们的孩子更新,然后离线处理。
最后一个选项可能是通过一些外部工具使用API。但是你仍然需要确保代码中的所有内容都已经完成。
我认为这些限制一开始是严苛的,但实际上如果你正确地批量处理,你可以在其中做很多事情,我们会定期从触发器更新1,000行。从架构的角度来看,远不止于此,你真的在谈论批量处理,而这通常不会被触发器激活。有一件事是肯定的 - 它们会让你跳过篮球去做。
答案 2 :(得分:1)
我认为Codek是对的,走API /外部工具路线是一个很好的方法。州长限制仍然适用,但对API调用的严格程度要低得多。 Salesforce最近修改了他们的DataLoader工具,因此可能需要考虑一下。
您可以尝试的另一件事是使用带有出站消息的工作流规则来调用您的Web服务。只需发送父对象,让你的进程通过API处理子记录更新。有一点需要注意出站邮件,最好以某种方式将流程排到最后,并立即响应Salesforce。否则Salesforce将重新发送消息。
答案 3 :(得分:1)
@future不起作用(根本不更新记录)?奇怪的。您是否尝试在自动测试中使用您的功能?它应该工作,并且应该忽略注释(在测试期间它将立即执行,测试方法有更高的限制)。我建议你再研究一下,这似乎是你想要完成的最佳解决方案。
另外 - 也许尝试从你的班级调用它,而不是触发器?
菊花链一起触发不起作用,我过去曾尝试过。
您的最后一个选项可能是批量Apex(来自Winter'10发布,所以所有组织都应该拥有它)。它适用于海量数据更新/验证作业,通常在正常数据库中过夜运行(可以安排)。请参阅http://www.salesforce.com/community/winter10/custom-cloud/program-cloud-logic/batch-code.jsp并发布说明PDF。
答案 4 :(得分:0)
我相信API的第18版已删除1000限制。 (所以文件说,但在某些情况下我仍然达到了极限)
所以你可以使用批量顶点。使用单个APEX更新声明
类似的东西:
列出儿童=新名单{};
for(childObect _c c:[SELECT ....]){
c.foo__c ='bar';
children.add(C);
} 更新(儿童);;
确保您的tigger扩大,请参阅http://sfdc.arrowpointe.com/2008/09/13/bulkifying-a-trigger-an-example/
答案 5 :(得分:0)
也许更改数据模型是更好的选择。考虑在子对象上创建一个公式,从父对象访问数据。这可能会更有效率。