【转载】salesforce 零基础开发入门学习(五)异步进程介绍与数据批处理Batchable
salesforce 零基础开发入门学习(五)异步进程介绍与数据批处理Batchable
salesforce对于数据操纵个数以及次数有严格的限制,超过限制值则抛出异常。
salesforce对于很多数据操纵的次数均有严格的限制。具体限制如下:
Number of SOQL queries: 100 -->一次执行SOQL的次数不能超过100次
Number of query rows: 50000 -->一次查出的数据行数不能超过50000条
Number of SOSL queries: 20 -->一次执行SOSL次数不能超过20次
Number of DML statements: 150 -->DML语句不能超过150条
Number of DML rows: 10000 -->一次操作数据行数不能超过10000行
Maximum CPU time: 10000 -->最大的CPU时间不能超过10000ms
Maximum heap size: 6000000 -->堆大小不能超过6000000B
Number of callouts:100 -->一次执行callouts次数不能超过100次
Number of Email Invocations: 10 -->Email调用次数不能超过10次
Number of future calls: 50 -->调用Future次数不能超过50次
Number of queueable jobs added to the queue:50 -->添加到队列的queueable job数量不能超过50次
Number of Mobile Apex push calls: 10 -->移动端Apex push调用最多不能超过10次
因为对于DML操作有限制,比如因为项目需求,需要修改50万条数据,直接调用Database.update()便会抛出异常,因为salesforce只允许一次性查出5万条数据并且只允许一次性修改1万条数据。如果需要达到目的,就只能使用批处理。
一)数据批处理Batchable
数据批处理适用于批量处理成百上千万的数据。批处理采用异步的处理方式处理数据,最多可以处理5000万条数据。新建一个批处理类需要实现Database.Batchable接口。此接口封装了三个方法,并且三个方法构成一个批处理的生命周期。start()方法用于查询数据,并将查询数据封装到List中;execute()方法用于操作数据,形参中List为start()方法中返回的数据,可以直接对此List进行修改以达到批处理行为。批处理全部执行后执行finish()方法,finish()方法用于进行一些后期处理,比如发邮件等操作。
需要注意的是:
1.start()方法执行后,数据便无法修改;
2.execute()原则上可以执行多次,比如在调用的时规定执行次数,则按照规定次数执行execute();
3.finish()方法执行以后,批处理类用到的所有的变量对象都会恢复到最开始的状态,即值回滚到最开始状态;
4.如果批处理类不实现Database.Stateful接口,则变量只在相应方法起作用,当方法执行完成,变量则会回滚到初始状态。
eg:在类中声明成员变量A,在start()方法对A进行处理,如果类不实现上述接口,则方法执行完start()方法后A会回滚到初始状态,在execute()方法或者finish()方法调用A时值为最开始声明的值,在start方法的处理结果不保留。
实现批处理类步骤明确,只需要执行以下的步骤:
1.实现Database.Batchable接口;
2.实现start()方法,此方法中通常写查询语句,并将数据通过Database.getQueryLocator(queryString)方法将数据传递到execute()形参中。此方法定义:
global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {} ;
3.实现execute()方法,此方法对数据进行DML操作。此方法定义:global void execute(Database.BatchableContext BC, list<P>){} ;
4.实现finish方法(),此方法进行后期处理,如果无需要处理,可以不进行处理。
上面步骤提到了Database.BatchableContext接口,此接口用于追踪批处理的进展。通过此接口可以获取相关的jobId,详情请参看官方文档。
下面举个例子,创建一个商品表GOODS__c,里面含有一个字段为价格GoodsPrice__c。现在需要将原来数据的GoodsPrice__c加1,代码如下:
implements Batchable
二)异步进程简单介绍
异步进程用于在单独的线程内来运行进程。异步进程是一个在后台运行,不需要用户等到任务结束的进程或者方法。异步进程好处很多,包括不需要用户等待,节省响应时间等等。
异步进程主要有以下几种形式:
| 类型 | 介绍 | 常用情景 |
| Future方法 | 在自己线程中运行,直到资源可用才运行 | Web service callout. |
| Batch Apex | 运行大量的Job,数量超过正常处理限制 | 数据DML操作 |
| QueueableApex | 和Future类似,但是提供额外的工作链,允许完成更复杂的类型 | 执行顺序处理操作与外部Web服务。 |
| ScheduledApex | 指定时间运行apex | 固定时间的任务,例如每日或每周等任务 |
- Future方法
Future方法用于异步处理,常用于Web service callout操作.Future方法需要有几个规范:
1.方法必须是静态static的;
2.方法上方需要使用@Future标签;
3.方法返回类型必须是void类型;
4.方法参数必须是模块私有的变量,不能使public等;
5.方法参数不允许使用标准的Object或sObject类型,可以使用基本类型或者集合类型;
6.不能再一个future方法调用另一个future方法,当future方法运行的时候也不可以在trigger中调用;
7.future方法中不能使用getContent()和getContentAsPDF()方法。
以下为Future方法代码举例。此方法用来输出符合Id在形参List中的所有Account的Id。
|
1
2
3
4
5
6
7
8
9
10
|
public with sharing class FutureSample { @future public static void futuremethod(List<ID> ids) { String sql = 'select Id,Name from Account where Id in :ids'; List<Account> accounts = Database.query(sql); for(Account account : accounts) { System.debug(account.Id); } }} |
有几点需要注意:
1)future方法执行不保证质量,如果需要好的质量可以使用Queueable方法;
2)可以允许两个future方法同时运行,当两个future方法同时对一条记录进行操作时,可能引起记录锁定或者运行时异常。
总之,使用future方式不保证质量。。。。。。而且有很多限制,开发的时候能不用就不用,如果必须使用情况下自己评估一下。
测试future方法在Test类中执行,和普通的方法测试区别的是,future方法执行需要在Test.startTest()和Test.stopTest()方法中进行.以下为测试代码:
|
1
2
3
4
5
6
7
8
9
|
@isTestprivate class Test_FutureSample { static testMethod void myUnitTest() { Test.startTest(); List<ID> ids= new ID[]{'0012800000Hz6ozAAB','0012800000Hz6oxAAB'}; FutureSample.futuremethod(ids); Test.stopTest(); }} |
- Queueable
Queueable接口有着类似future的特性,类似将future特性和批处理功能混合在一起,相对future方法来讲,有很大的优势:
1.可以使用Object和sObject类型作为参数;
2.便于监控,可以直接通过System.enqueueJob()方法运行返回AsyncApexJob ,方法不用限制在startTest()和stopTest()方法中;
3.可以链接两个job,一个Queueable接口方法可以调用另一个Queueable接口。
Queueable在执行异步的时候大部分可以替代掉future,但是不是所有的情况都可以替换。当一个方法有时需要同步执行有时需要异步执行,相对来讲用future操作更为简单,毕竟不需要修改方法的内容,只是注解而已。
Queueable接口代码举例:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public with sharing class QueueableSample implements Queueable{ private List<ID> ids{get;set;} public QueueableSample(List<ID> ids) { this.ids = ids; } public void execute(QueueableContext qc) { String sql = 'select Id,Name from Account where Id in :ids'; List<Account> accounts = Database.query(sql); for(Account account : accounts) { System.debug(account.Id); } }} |
运行实现QueueableSample接口的类的方式如下:
|
1
2
3
4
5
6
7
8
9
10
|
@isTestprivate class Test_QueueableSample { static testMethod void myUnitTest() { Test.startTest(); List<ID> ids= new ID[]{'0012800000Hz6ozAAB','0012800000Hz6oxAAB'}; QueueableSample sample = new QueueableSample(ids); ID jobID = System.enqueueJob(sample); Test.stopTest(); }} |
Queueable尽管很好用很强大,不过force.com对于Queueable有很多限制和规范,详情请参看官方文档。
- ScheduledApex
定时任务相对来说,使用比较方便。当你需要在指定时间日期去执行某些操作(比如定期清理垃圾数据等等)时,定时任务就显得尤为便利。
定时任务的声明和调用都很简单,通过以下步骤即可完成操作:
1.实现Schedulable接口,并重写execute方法,此方法体内实现需要定时执行的操作;
2.使用System.schedule()方法实现定时任务的调用。
Schedulable接口代码举例如下:
|
1
2
3
4
5
6
7
|
public class GoodsSchedule implements Schedulable { public void execute(SchedulableContext sc) { String queryString = 'select Id,GOODSNAME__c from GOODS__c'; SimpleBatchUtil batchUtil = new SimpleBatchUtil(queryString); Database.executeBatch(batchUtil); }} |
上述代码定义了一个定时任务,定时任务的方法体内实现批处理操作GOODS表
Schedulable接口调用如下所示:
|
1
2
3
4
5
6
7
8
9
|
@isTestprivate class TestGoodsSchedule { static testMethod void myUnitTest() { String executeTime = '0 10 2 * * ?'; GoodsSchedule goodsSchedule = new GoodsSchedule(); System.schedule('batch goods',executeTime,goodsSchedule); }} |
注意:定时任务在每24小时同时只允许最多100个定时任务。超过数量则会抛出异常。
System.schedule()方法有三个参数:第一个参数为定时任务名称;第二个参数为定时任务执行时间;第三个参数为需要执行的定时任务的对象。
关于定时任务执行时间有很多需要注意的地方:
执行时间字符串通过空格分隔每个时间点,时间点的顺序为:
Seconds Minutes Hours Day_of_month Month Day_of_week optional_year
每个时间点的取值如下所示:
| 名称 | 取值范围 | 特殊字符 |
| Seconds | 0-59 | NONE |
| Minutes | 0-59 | NONE |
| Hours | 23 | , - * / |
| Day_of_month | 1--31 | , - * / ? L W |
| Month |
1--12或者JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC |
, - * / |
| Day_of_week | 1--7或者SUN,MON,TUE,WED,THU,FRI,SAT | , - * / ? L # |
| optional_year | null或者1970--2099 | , - * / |
特殊字符包含八种,下面是对他们的解释:
| 特殊字符名称 | 特殊字符解释 |
| , | 定界值。比如Hours设置1,2则只有小时为1或者2的时候执行 |
| - | 指定一个范围。比如Day_of_week设置2-6则周一到周五执行 |
| * | 指定所有值。比如Day_of_month指定*则每天都执行 |
| ? | 没有指定特定的值,只在Day_of_month和Day_of_week中执行 |
| / | /左侧指定间隔什么时间开始,/右侧显示间隔数量。eg:对于Day_of_month,指定1/5则每个月的每个第五天开始运行第一天 |
| L | 只应用于Day_of_month以及Day_of_week.用于Day_of_month代表当月最后一天,用于Day_of_week,代表每月最后一个周几. eg : 1L代表每月最后一个周日 |
| W | 只应用于Day_of_month.指定最接近与当天的工作日,比如指定20W,20为周六,则值为19,即星期五。如果指定1W,1为周六,最接近的为上个月,则不可取,取第三日,即周一。 |
| # | 只应用于Day_of_week.格式为weekday#day_of_month。其中,#以前代表工作日1-7(周日-周六),#以后指定月的第几天。eg:2#2代表每个月第二个周一执行。 |
通过几个例子举例:
0 0 13 * * ? 指定每天13点执行
0 0 22 ? * 6L 指定每个月最后一个周五22点执行
0 0 10 ? * MON-FRI 指定周一到周五10点执行
0 0 20 * * ? 2016 2016年每天20点执行
Schedulable除了在代码中通过System.schedule()方法启动定时任务还可以通过页面设置启动定时器。步骤如下:
1.点击setup-->develop-->Apex Classes;
2.点击Schedule Apex按钮;
3.输入Job Name,为定时任务显示的任务名称,点击Apex Class的查找按钮选择需要定时任务的实现Schedulable接口的类,设定时间,点击保存;
4.定时任务创建成功,在setup-->Jobs-->Scheduled Jobs中可以看到创建的定时任务了。
通过页面设置启动定时器和代码的区别为:使用页面配置定时器无法精确到分和秒。
由于本人对于Salesforce也是一个小白,所以如果有的内容有错误,欢迎批评指正。如果有不懂的问题,可以留言,大家共同探讨。下一篇将描述简单的数据增删改查页面的构建。
【转载】salesforce 零基础开发入门学习(五)异步进程介绍与数据批处理Batchable的更多相关文章
- 【转载】salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建
salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建 VisualForce封装了很多的标签用来进行页面设计,本篇主要讲述简单的页面增删改查.使用的内容和设计到前台页面使用的 ...
- salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建
VisualForce封装了很多的标签用来进行页面设计,本篇主要讲述简单的页面增删改查.使用的内容和设计到前台页面使用的标签相对简单,如果需要深入了解VF相关知识以及标签, 可以通过以下链接查看或下载 ...
- 【转载】salesforce 零基础开发入门学习(一)Salesforce功能介绍,IDE配置以及资源下载
salesforce 零基础开发入门学习(一)Salesforce功能介绍,IDE配置以及资源下载 目前国内已经有很多公司做salesforce,但是国内相关的资料确是少之又少.上个月末跳槽去了新 ...
- 【转载】salesforce 零基础开发入门学习(四)多表关联下的SOQL以及表字段Data type详解
salesforce 零基础开发入门学习(四)多表关联下的SOQL以及表字段Data type详解 建立好的数据表在数据库中查看有很多方式,本人目前采用以下两种方式查看数据表. 1.采用schem ...
- 【转载】salesforce 零基础开发入门学习(三)sObject简单介绍以及简单DML操作(SOQL)
salesforce 零基础开发入门学习(三)sObject简单介绍以及简单DML操作(SOQL) salesforce中对于数据库操作和JAVA等语言对于数据库操作是有一定区别的.salesfo ...
- 【转载】salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句
salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句 salesforce如果简单的说可以大概分成两个部分:Apex,VisualForce Page. 其中Apex ...
- salesforce 零基础开发入门学习(五)异步进程介绍与数据批处理Batchable
本篇知识参考:https://developer.salesforce.com/trailhead/force_com_dev_intermediate/asynchronous_apex/async ...
- salesforce 零基础开发入门学习(一)Salesforce功能介绍,IDE配置以及资源下载
目前国内已经有很多公司做salesforce,但是国内相关的资料确是少之又少.上个月末跳槽去了新公司,主要做的就是salesforce,不过当时想要看一些相关资料确实比较难.为了避免想要零基础学习的人 ...
- salesforce 零基础开发入门学习(十一)sObject及Schema深入
sObject在salesforce中占有举足轻重的位置,除了在数据库中数据以外,我们还应该关心一下他的元信息.元信息封装在Schema命名空间内. 作为面向对象语言,我们可以畅想一下如果我们是设计人 ...
随机推荐
- lombok编译时注解@Slf4j的使用及相关依赖包
slf4j是一个日志门面模式的框架,只对调用者开放少量接口用于记录日志 主要接口方法有 debug warn info error trace 在idea中可以引入lombok框架,使用@Slf4j注 ...
- Golang 项目 GOPATH 总结
查看GOPATH go env 项目里执行:go get github/winyh/XXX 命令时, 包会下载到 GOPATH第一个目录下的src文件夹 项目里引入依赖的时候会自动到GOPATH里 ...
- tensorflow学习 从入门到实战(转)
原文作者:zhaozhengcoder链接:https://www.jianshu.com/p/27a2fb320934來源:简书简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处. ...
- AWS 云上安全最佳实践
目录 一.账号及访问管理 1.1.多 VPC 还是多账号模式 1.2.多账户模式,选择主 master 账号 二.系统架构安全 2.1.子网建议 2.2.每个可用区子网划分 2.3.安全组的建议 2. ...
- demo rabbitmq topic(主题模式),fanout(广播模式),轮询分发,确认接收Ack处理
//durable = true 代表持久化 交换机和队列都要为true ,持久代表服务重启,没有处理的消息依然存在 //topic 根据不同的routkey 发送和接收信息 //fanout 广播模 ...
- Hadoop概念学习系列之Hadoop、Spark学习路线
1 Java基础: 视频方面: 推荐<毕向东JAVA基础视频教程>.学习hadoop不需要过度的深入,java学习到javase,在Java虚拟机的内存管理.以及多线程. ...
- Qt598x64vs2017.Kit(构建套件)(安装Qt598x86vs2015)
1.Qt598-->工具-->选项 1.1. 1.2. 2.20191120 想起 上面第一张图的配置编译器的地方,就想着 Qt598x64vs2017 配置成编译x86,于是将 上面图中 ...
- SpringBoot Profile使用详解及配置源码解析
在实践的过程中我们经常会遇到不同的环境需要不同配置文件的情况,如果每换一个环境重新修改配置文件或重新打包一次会比较麻烦,Spring Boot为此提供了Profile配置来解决此问题. Profile ...
- Codis的安装配置
codis是分布式redis解决方案 centos系统下安装codis需要安装相关的依赖,将图中的依赖上传至centos系统中 依次进行安装: 一.go环境的安装配置 解压到install目录下: . ...
- CentOS系统安装启动tomcat
我们可以通过xftp工具将tomcat文件上传至CentOS系统指定文件夹中 一.安装tomcat 进入tomcat存放目录解压: tar -zxf apache-tomcat-9.0.2.tar.g ...