salesforce零基础学习(一百零五)Change Data Capture

时间:2021-09-25 00:25:56

本篇参考:

https://developer.salesforce.com/docs/atlas.en-us.232.0.api_streaming.meta/api_streaming/using_streaming_api_durability.htm

https://trailhead.salesforce.com/content/learn/modules/change-data-capture

https://developer.salesforce.com/docs/atlas.en-us.change_data_capture.meta/change_data_capture/cdc_intro.htm

https://developer.salesforce.com/blogs/2018/08/what-is-change-data-capture.html

https://developer.salesforce.com/docs/atlas.en-us.232.0.object_reference.meta/object_reference/sforce_api_associated_objects_change_event.htm

salesforce零基础学习(九十六)Platform Event浅谈

salesforce零基础学习(八十五)streaming api 简单使用(接近实时获取你需要跟踪的数据的更新消息状态)

我们在前面介绍过 Push Topic 以及 Platform Event这两个 Streaming API,可以想象未来的某天肯定还会补上一篇 Change Data Capture(CDC) 集齐 Streaming API 三件套,今天这篇博客就是对CDC进行浅入浅出。

一. CDC 概念以及什么时候使用

提起CDC以前,还是需要先重新说一下 Streaming Event 以及 Push technology。 Streaming Event(流事件)是一个系统(发布者)向另一个系统(订阅者)发送的即时通知消息。使用推送技术,发布者将数据推送到订阅者,这个操作近乎实时。对Streaming API感兴趣或者不了解的,可以查看上文的第一个链接。Streaming Event在salesforce中主要有三种封装好的feature: Push Topic & Platform Event & Change Data Capture.

salesforce零基础学习(一百零五)Change Data Capture

所以什么场景下我们推荐使用 Change Data Capture呢?使用CDC有哪些优势,什么场景不建议呢?

  • 使外部系统与Salesforce数据保持同步;
  • 接收Salesforce记录更改的通知,包括创建、更新、删除和取消删除操作;
  • 可以通过CometD或者Apex Trigger去订阅;
  • 捕获所有记录的字段变更;
  • 无论共享规则如何,订阅者都可以广泛访问所有数据;
  • 订阅者基于Field Level Security,仅传递用户有权访问的字段;
  • 加密 change event字段;
  • 在事件的header中获取有关更改的信息,例如更改的来源等,它可以让订阅方更灵活的判断操作数据;
  • 使用事务边界执行数据更新;
  • 使用版本化的事件架构;
  • 以可扩展的方式订阅大量更改;
  • 访问保留的事件最多三天。

以下场景不适用于使用CDC。

  • 根据记录和字段更改执行审核跟踪。
  • 更改数据捕获旨在保持下游系统的同步,而不是单个用户。如果许多用户订阅了CometD客户机,那么并发客户机限制可能会达到。

二. CDC的发布,结构以及订阅

既然我们知道哪些场景推荐使用,那么我们应该清楚如何去发布,以及发送出去的结构和限制等细节知识,用来做一些评估和下游系统的对接。

发布篇:

setup->  change data capture 然后选择我们需要追踪的表即可。这里我们选择了 Account以及 Opportunity,则Account 以及 Opportunity有CUD情况,下游订阅端便可以获取到消息数据。

salesforce零基础学习(一百零五)Change Data Capture

结构篇:

那下游端订阅需要了解一下CDC推送过去的格式是什么样,否则他们也没法去进行解析操作,所以我们来看一下CDC推送的消息数据的格式。

通过下图我们看到一个CDC的消息数据结构可以简单的分成两部分: header & body。 header用来记录推送的表的信息,比如表名,操作的类型(CUD/UnDelete),操作的表的ID信息等等。body部分即为改动的字段的信息的键值队。针对新增场景,发送所有的非空的字段以及系统字段;针对更新场景,发送所有改变了的字段;针对删除场景,不会有任何的字段。细节可以查看一下官方的API文档。

salesforce零基础学习(一百零五)Change Data Capture

这里来做一个引申,如果系统中有formula字段,在新增或者更新场景并不会发送过去,所以针对 formula字段,如果使用了CDC需要考虑进行单独的处理,如果前期未识别,后续会增加很多effort来对应。现在看上面这个截图可能有点懵,等会通过trigger订阅打印出来以后可以更好的了解报文内容。

订阅篇:

salesforce针对CDC支持两种订阅方式: CometD以及Apex Trigger,针对 CometD不做介绍,PushTopic & Platform Event & CDC都是支持CometD订阅方式,如果涉及到下游系统,直接根据官方文档中的demo一步一步配置,很轻松的就可以实现。这里主要是介绍一下 Apex Trigger方式订阅。

要知道,如果我们使用 PushTopic方式订阅,如果下游系统真的没收到数据是一个很麻烦的事情,我们没法去和他们解释到底是salesforce没有广播这条数据,还是订阅端问题,会有适当的扯皮操作,但是使用CDC我们完全不会有这个疑问,因为当广播出去以后,我们可以通过trigger去实现订阅从而实现tracking。不是所有的表都支持CDC,所以我们可以去查看一下官方文档来确定一下。针对支持的表,trigger的写法和 ApexTrigger很相似,区别就是监控的表为 [Object]ChangeEvent。如果是标注你的表,则直接使用名称,比如 AccountChangeEvent。如果是自定义表,则中间需要加上两个下划线,比如 CustomObject__ChangeEvent。并且只允许 after insert使用。下面的例子是针对 OpportunityChangeEvent进行监听,如果是Stage为Close Won情况下,创建一个Task。通过这个trigger,我们也可以打印出来实际的这个结构。

trigger OpportunityChangeTrigger on OpportunityChangeEvent (after insert) {
List<Task> tasks = new List<Task>();
// Iterate through each event message.
for (OpportunityChangeEvent event : Trigger.New) {
// Get some event header fields
EventBus.ChangeEventHeader header = event.ChangeEventHeader;
system.debug('event : ' + JSON.serialize(event));
if (header.changetype == 'UPDATE') {
System.debug('List of all changed fields:');
for (String field : header.changedFields) {
if (null == event.get(field)) {
System.debug('Deleted field value (set to null): ' + field);
} else {
System.debug('Changed field value: ' + field + '. New Value: '
+ event.get(field));
}
}
}
if ((header.changetype=='UPDATE') && (event.isWon==true)) {
// Create a task
Task tk = new Task();
tk.Subject = 'Follow up on won opportunities: ' + header.recordIds;
tk.OwnerId = header.CommitUser;
tasks.add(tk);
}
}
// Insert all tasks in bulk.
if (tasks.size() > 0) {
insert tasks;
}
}

需要知道的是,如果我们希望在debug log中查看到CDC相关的订阅信息,需要将 Traced Entity Type设置成 Automated Process。

salesforce零基础学习(一百零五)Change Data Capture

我们新建一条 Opportunity的情况下,以下是创建的内容。

salesforce零基础学习(一百零五)Change Data Capture

可以看一下message 的结构,其中包括了当前的类型,以及变更的字段以及其字段对应的值,通过header我们可以看到这条记录执行的是CREATE的操作。不是所有的字段都展示在这里,只有内容非空的才会在body中。

{
"IsClosed": false,
"attributes": {
"url": "/services/data/v52.0/sobjects/OpportunityChangeEvent/4881111",
"type": "OpportunityChangeEvent"
},
"IsWon": false,
"IsSplit": false,
"CloseDate": "2021-07-10",
"ReplayId": "4881111",
"ForecastCategory": "Pipeline",
"Name": "测试CDC 0710",
"IsExcludedFromTerritory2Filter": false,
"Probability": 10,
"OwnerId": "0053g000000lqx1AAA",
"LastModifiedDate": "2021-07-10T15:58:07.000+0000",
"Id": "1CExx000000KTnbGAG",
"HasOpportunityLineItem": false,
"StageName": "Prospecting",
"IsPrivate": false,
"ForecastCategoryName": "Pipeline",
"LastModifiedById": "0053g000000lqx1AAA",
"CreatedById": "0053g000000lqx1AAA",
"ChangeEventHeader": {
"recordIds": [
"0063g00000AQHUwAAP"
],
"nulledFields": [],
"diffFields": [],
"commitUser": "0053g000000lqx1AAA",
"entityName": "Opportunity",
"changeType": "CREATE",
"commitNumber": 11077894054001,
"changedFields": [],
"commitTimestamp": 1625932687000,
"changeOrigin": "com/salesforce/api/soap/52.0;client=SfdcInternalAPI/",
"transactionKey": "00038c39-bc36-b76b-776e-d489f264045f",
"sequenceNumber": 1
},
"CreatedDate": "2021-07-10T15:58:07.000+0000"
}

将这条数据进行update操作,设置amount,并且修改一下Stage Name

salesforce零基础学习(一百零五)Change Data Capture

我们可以看一下message详情架构如下:body中拥有了 Amount信息以及修改的字段的信息。我们可以看到现在的change Type是 UPDATE。在header的changedFields区域就可以看到这次修改的哪些字段。

{
"IsClosed": false,
"attributes": {
"url": "/services/data/v52.0/sobjects/OpportunityChangeEvent/4890418",
"type": "OpportunityChangeEvent"
},
"Amount": 101.0,
"LastModifiedDate": "2021-07-11T05:40:20.000+0000",
"IsSplit": false,
"HasOpportunityLineItem": false,
"LastAmountChangedHistoryId": "0083g00000KllvXAAR",
"IsExcludedFromTerritory2Filter": false,
"Id": "1CExx000000KWDiGAO",
"ReplayId": "4890418",
"StageName": "Needs Analysis",
"IsPrivate": false,
"LastStageChangeDate": "2021-07-11T05:40:20.000+0000",
"IsWon": false,
"ChangeEventHeader": {
"recordIds": [
"0063g00000AQHUwAAP"
],
"nulledFields": [],
"diffFields": [],
"commitUser": "0053g000000lqx1AAA",
"entityName": "Opportunity",
"changeType": "UPDATE",
"commitNumber": 11078205948865,
"changedFields": [
"StageName",
"Amount",
"ExpectedRevenue",
"LastModifiedDate",
"LastStageChangeDate",
"LastAmountChangedHistoryId"
],
"commitTimestamp": 1625982020000,
"changeOrigin": "com/salesforce/api/soap/52.0;client=SfdcInternalAPI/",
"transactionKey": "0003bba5-8a9b-2ad2-c3c3-a15a295b2bb5",
"sequenceNumber": 1
},
"ExpectedRevenue": 20.2
}

三. CDC 、 PushTopic、Platform Event 区别

我们作为开发人员还好,可能架构选型以后,我们了解做了就好。但是哪天我们做到了架构,需要我们选型相关的,我们如何去选型呢?这三个有什么区别或者优缺点,如何去取舍?下图是我们官方的一个比较,详情链接:https://developer.salesforce.com/docs/atlas.en-us.232.0.api_streaming.meta/api_streaming/event_comparison.htm?search_text=Platform%20Event

salesforce零基础学习(一百零五)Change Data Capture

除了这种 high level的比较,一定要确定好选型以后的细节考虑。比如 PushTopic的query的长度限制,Change Data Capture formula字段变更不会传过去,而且超过指定的数量需要花钱等等。high level决定选型,细节决定了你的effort,缺一不可。

总结:篇中浅入浅出介绍了一下CDC的使用,至此streaming api 广播订阅的三个模型都已经有简单介绍。很多细节介绍也没有展开,比如trigger一次进入数据的数据量必须2000以内等等。如果用到了这个模型,详细查看官方文档进行夯实即可。篇中有错误欢迎指出,有不懂欢迎留言。

salesforce零基础学习(一百零五)Change Data Capture的更多相关文章

  1. MVC&plus;Ext&period;net零基础学习记录(五)

    继MVC+Ext.net零基础学习记录(四),在后面我在既有的项目上又添加了一个子项目,还用前面提到的方法,进行主项目中引用DLL,然后子项目中生成事件中使用mkdir 进行拷贝 发现一个下午就总是报 ...

  2. salesforce零基础学习(九十五)lightning out

    随着salesforce对lightning的推进,越来越多的项目基于lightning开发,导致很多小伙伴可能都并不了解classic或者认为不需要用到classic直接就开始了lightning的 ...

  3. salesforce零基础学习(一百一十)list button实现的一些有趣事情

    本篇参考: salesforce零基础学习(九十五)lightning out https://developer.salesforce.com/docs/component-library/docu ...

  4. salesforce 零基础学习(五十二)Trigger使用篇(二)

    第十七篇的Trigger用法为通过Handler方式实现Trigger的封装,此种好处是一个Handler对应一个sObject,使本该在Trigger中写的代码分到Handler中,代码更加清晰. ...

  5. salesforce lightning零基础学习&lpar;十五&rpar; 公用组件之 获取表字段的Picklist&lpar;多语言&rpar;

    此篇参考:salesforce 零基础学习(六十二)获取sObject中类型为Picklist的field values(含record type) 我们在lightning中在前台会经常碰到获取pi ...

  6. salesforce零基础学习(九十六)Platform Event浅谈

    本篇参考:https://developer.salesforce.com/blogs/2018/07/which-streaming-event-do-i-use.html https://trai ...

  7. salesforce零基础学习(八十)使用autoComplete 输入内容自动联想结果以及去重实现

    项目中,我们有时候会需要实现自动联想功能,比如我们想输入用户或者联系人名称,去联想出系统中有的相关的用户和联系人,当点击以后获取相关的邮箱或者其他信息等等.这种情况下可以使用jquery ui中的au ...

  8. salesforce 零基础学习(六十八)http callout test class写法

    此篇可以参考: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restfu ...

  9. salesforce零基础学习(八十二)审批邮件获取最终审批人和审批意见

    项目中,审批操作无处不在.配置审批流时,我们有时候会用到queue,related user设置当前步骤的审批人,审批人可以一个或者多个.当审批人有多个时,邮件中获取当前记录的审批人和审批意见就不能随 ...

随机推荐

  1. Uncaught ReferenceError&colon; XXX is not defined

    Uncaught ReferenceError: XXX is not defined 这个问题困扰我很久,虽然找到了解决方法,但是还不是很明白. 如下所示:是报错的代码. 如果把它改成下面的形式就可 ...

  2. u-boot 环境变量参数设置

    今天本来是烧写内核,结果一不小心把uboot也整不能用了,无奈之下只好重新烧个uboot,等都弄好以后,发现系统还是启动不了,原来是启动参数设置不对,于是找到了这篇文章,//是我添加的内容. 原文地址 ...

  3. Java设计模式(八)Proxy代理模式

    一.场景描述 代理在生活中并不少见,租房子需要找中介,打官司需要找律师,很多事情我们需要找专业人士代理我们做,另一方面,中介和律师也代理了房东.法律程序与我们打交道. 当然,设计模式中的代理与广义的代 ...

  4. js 屏蔽政治关键字

    一般情况下,用户输入评论提交到后台的同时,在后台进行关键字过滤,昨天看到了一个js关键字过滤的方法,记录下. 方法很简单,先把需要过滤的关键字做成数组, 在for循环数组判断有没有匹配. ok,先来个 ...

  5. 二叉树&sol;DFS总结

    二叉搜索树(Binary Search Tree,又名排序二叉树,二叉查找树,通常简写为BST)定义如下: 空树或是具有下列性质的二叉树: ()若左子树不空,则左子树上所有节点值均小于或等于它的根节点 ...

  6. project 2013 显示标题

    1.分析 右键只能插入任务,不能插入标题,而插入任务会被编号,目前只能在打印设置标题,不能在编辑界面显示标题的,或者使用*任务的方式 2.解决 文件,打印,页面设置,页眉,居中,输入标题,这样打印 ...

  7. 微信小程序之自定义select下拉选项框组件

    知识点:组件,animation,获取当前点击元素的索引与内容 微信小程序中没有select下拉选项框,所以只有自定义.自定义的话,可以选择模板的方式,也可以选择组件的方式来创建. 这次我选择了组件, ...

  8. 在命令行上 Ubuntu 下使用 mutt 和 msmtp 发送 Gmail 邮件

    在命令行写email from ubuntu 参考:      http://www.habadog.com/2011/11/23/send-mail-with-msmtp-mutt-linux    ...

  9. supervisor 日志轮转

    Supervisord 会基于 logfile_maxbytes 和 logfile_backups 轮转日志.当活跃日志文件大小达到 logfile_maxbytes,这个文件会被重命名为备份文件, ...

  10. django通过使用jwt模块实现状态保持

    第一步:安装jwt pip install djangorestframework-jwt 第二步:settings/dev的配置文件配置 REST_FRAMEWORK = { # 认证配置 'DEF ...