由于Apex是在多租户平台运行的,所以有各种各样的限制,来避免失控的Apex占用太多资源。
下面介绍几个常见的governors。
1.发出的SOQL查询总数
在每个事务中,同步Apex的soql查询总数最大为100,sosl查询总数最大是20。异步Apex中soql的查询总数最大是200,sosl是20。
同步Apex
在console中执行下面的代码,程序正常执行,相应的资源已经占满。
// soql 最大100
String sql = 'SELECT Id FROM Account LIMIT 1';
for(Integer i = 0; i < 100; i++){
Account acc = Database.query(sql);
}
// sosl 最大20
for(Integer i = 0; i < 20; i++){
List<List<sObject>> acc = [FIND 'test1148' IN ALL FIELDS RETURNING Account(Id,Name)];
}
修改for循环次数,soql循环次数改成101程序报错。
Too many SOQL queries:101
// soql 最大100
String sql = 'SELECT Id FROM Account LIMIT 1';
for(Integer i = 0; i < 101; i++){
Account acc = Database.query(sql);
}
// sosl 最大20
for(Integer i = 0; i < 20; i++){
List<List<sObject>> acc = [FIND 'test1148' IN ALL FIELDS RETURNING Account(Id,Name)];
}
sosl循环次数改成21,程序报错。
Too many SOSL queries:21
// soql 最大100
String sql = 'SELECT Id FROM Account LIMIT 1';
for(Integer i = 0; i < 100; i++){
Account acc = Database.query(sql);
}
// sosl 最大20
for(Integer i = 0; i < 21; i++){
List<List<sObject>> acc = [FIND 'test1148' IN ALL FIELDS RETURNING Account(Id,Name)];
}
异步Apex
比如batch apex,代码如下。
public class LimitBatch implements Database.Batchable<sObject>{
public Database.QueryLocator start(Database.BatchableContext bc){
String query = 'SELECT Id FROM Account LIMIT 10';
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext bc, List<sObject> scope){
// soql 最大200
String query = 'SELECT Id FROM Account LIMIT 1';
for(Integer i = 0; i < 200; i++){
Account acc = Database.query(query);
}
// sosl 最大20
for(Integer i = 0; i < 20; i++){
List<List<sObject>> acc = [FIND 'test1148' IN ALL FIELDS RETURNING Account(Id,Name)];
}
}
public void finish(Database.BatchableContext bc){}
}
当循环次数是200次是,也就是执行200次soql时,代码正常运行。
把执行soql的次数改成201后,代码报错。 Too many SOQL queries:201
把执行sosl的次数改成21后,代码报错。Too many SOSL queries:21
2.SOQL查询到的记录总数
在每个事务中,每条soql查询到的记录数最大是50000,sosl查询到的记录数最大是2000。
3.DML语句总数
在每个事务中,同步和异步Apex中都最多有150个DML语句。
当遍历次数是150时,程序正常执行。
Account acc = [SELECT Id, Name FROM Account LIMIT 1];
for(Integer i = 0; i < 150; i++){
acc.name = 'testDML150';
update acc;
}
当遍历151次时,代码报错。Too many DML statements:151
Account acc = [SELECT Id, Name FROM Account LIMIT 1];
for(Integer i = 0; i < 151; i++){
acc.name = 'testDML150';
update acc;
}
DML语句包括:
- Approval.process
- Database.convertLead
- Database.emptyRecycleBin
- Database.rollback
- Database.setSavePoint
- delete and Database.delete
- insert and Database.insert
- merge and Database.merge
- undelete and Database.undelete
- update and Database.update
- upsert and Database.upsert
- EventBus.publish for platform events configured to publish after commit
- System.runAs