{"id":11389,"date":"2018-07-02T21:02:43","date_gmt":"2018-07-02T19:02:43","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/"},"modified":"2018-07-02T21:02:43","modified_gmt":"2018-07-02T19:02:43","slug":"event-sourcing-cqn-is-not-a-replacement-for-cdc","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/","title":{"rendered":"Event Sourcing: CQN is not a replacement for CDC"},"content":{"rendered":"<h2>By Franck Pachot<\/h2>\n<p>.<br \/>\nWe are in an era where software architects want to stream the transactions out of the database and distribute them, as events, to multiple microservices. Don&#8217;t ask why, but that&#8217;s the trend: store <del>inconsistent<\/del> eventually consistent copies of data in different physical components, rather than simply using logical views in the same database, where the data is ACIDely stored, processed and protected. Because it was decided that this segregation, in CQRS (Command Query Responsibility Segregation), will be physical, on different systems, the need for logical replication and change data capture is raising, with a new name: Event Sourcing.<br \/>\n<!--more--><br \/>\nWhen we want to replicate the changes without adding an overhead to the database, the solution is Change Data Capture from the redo stream. The redo contains all the physical changes and, with dictionary information and a little supplemental logging, we can mine it to extract the logical changes. Currently are commercial products (Oracle GoldenGate, Attunity, Dbvisit replicate) and there are some open source ones based on LogMiner (StreamSets, Debezium). LogMiner is available on all Oracle Database editions without any option. In Enterprise Edition, a more efficient solution was possible with Streams but now you have to pay for GoldenGate to use Streams. Unfortunately, sometimes you pay software update to get features removed and be sold in additional products.<\/p>\n<p>Oracle has another feature that can help to replicate changes: Database Change notification, now known as Continuous Query Notification (CQN) or Object Change Notification (OCN). This feature has been implemented to refresh caches: you have a query that loads the cache and you want to be notified when some changes occurred, so that you have to update\/refresh the cache. Then, in theory, this can be used to stream out the changes. However, CQN was not built for frequent changes but rather for nearly static, or slowly changing data. But sometimes we have to test by ourselves and here are my test using CQN with a lot of changes on the underlying table, just to show how it increases the load on the database and slows down the changes.<\/p>\n<p>I create a DEMO table with one million rows:<\/p>\n<pre><code>\n17:21:56 SQL&gt; whenever sqlerror exit failure;\n17:21:56 SQL&gt; create table DEMO (ID constraint DEMO_ID primary key) as select rownum from xmltable('1 to 1000000');\n&nbsp;\nTable DEMO created.\n&nbsp;\n<\/code><\/pre>\n<p>And a table to hold notifications. As always when I want to start with an example, I start to get it from <a href=\"https:\/\/oracle-base.com\/articles\/10g\/dbms_change_notification_10gR2\" target=\"_blank\" rel=\"noopener noreferrer\">oracle-base<\/a>:<\/p>\n<pre><code>\n17:21:58 SQL&gt; -- from Tim Hall https:\/\/oracle-base.com\/articles\/10g\/dbms_change_notification_10gR2\n17:21:58 SQL&gt; CREATE TABLE notifications (\n  2    id                 NUMBER,\n  3    message            VARCHAR2(4000),\n  4    notification_date  DATE\n  5  );\n&nbsp;\nTable NOTIFICATIONS created.\n&nbsp;\n17:21:58 SQL&gt; CREATE SEQUENCE notifications_seq;\n&nbsp;\nSequence NOTIFICATIONS_SEQ created.\n<\/code><\/pre>\n<p>The callback function:<\/p>\n<pre><code>\n17:21:58 SQL&gt; CREATE OR REPLACE PROCEDURE callback (ntfnds IN SYS.chnf$_desc) IS\n  2    l_regid           NUMBER;\n  3    l_table_name      VARCHAR2(60);\n  4    l_event_type      NUMBER;\n  5    l_numtables       NUMBER;\n  6    l_operation_type  NUMBER;\n  7    l_numrows         NUMBER;\n  8    l_row_id          VARCHAR2(20);\n  9    l_operation       VARCHAR2(20);\n 10    l_message         VARCHAR2(4000) := NULL;\n 11  BEGIN\n 12    l_regid      := ntfnds.registration_id;\n 13    l_numtables  := ntfnds.numtables;\n 14    l_event_type := ntfnds.event_type;\n 15    IF l_event_type = DBMS_CHANGE_NOTIFICATION.EVENT_OBJCHANGE THEN\n 16      FOR i IN 1 .. l_numtables LOOP\n 17        l_table_name      := ntfnds.table_desc_array(i).table_name;\n 18        l_operation_type  := ntfnds.table_desc_array(i).Opflags;\n 19        IF (BITAND(l_operation_type, DBMS_CHANGE_NOTIFICATION.ALL_ROWS) = 0) THEN\n 20          l_numrows := ntfnds.table_desc_array(i).numrows;\n 21        ELSE \n 22          l_numrows :=0;  \/* ROWID INFO NOT AVAILABLE *\/\n 23        END IF;\n 24        CASE\n 25          WHEN BITAND(l_operation_type, DBMS_CHANGE_NOTIFICATION.INSERTOP) != 0 THEN\n 26            l_operation := 'Records Inserted';\n 27          WHEN BITAND(l_operation_type, DBMS_CHANGE_NOTIFICATION.UPDATEOP) != 0 THEN\n 28            l_operation := 'Records Updated';\n 29          WHEN BITAND(l_operation_type, DBMS_CHANGE_NOTIFICATION.DELETEOP) != 0 THEN\n 30            l_operation := 'Records Deleted';\n 31          WHEN BITAND(l_operation_type, DBMS_CHANGE_NOTIFICATION.ALTEROP) != 0 THEN\n 32            l_operation := 'Table Altered';\n 33          WHEN BITAND(l_operation_type, DBMS_CHANGE_NOTIFICATION.DROPOP) != 0 THEN\n 34            l_operation := 'Table Dropped';\n 35          WHEN BITAND(l_operation_type, DBMS_CHANGE_NOTIFICATION.UNKNOWNOP) != 0 THEN\n 36            l_operation := 'Unknown Operation';\n 37          ELSE\n 38            l_operation := '?';\n 39        END CASE;\n 40        l_message := 'Table (' || l_table_name || ') - ' || l_operation || '. Rows=' || l_numrows;\n 41        INSERT INTO notifications (id, message, notification_date)\n 42        VALUES (notifications_seq.NEXTVAL, l_message, SYSDATE);\n 43        COMMIT;\n 44      END LOOP; \n 45    END IF;      \n 46  END;\n 47  \/\n&nbsp;\nProcedure CALLBACK compiled\n&nbsp;\n17:21:58 SQL&gt; -- thanks Tim \n<\/code><\/pre>\n<p>and the CQN registration:<\/p>\n<pre><code>\n17:21:58 SQL&gt; -- register on DEMO;\n17:21:58 SQL&gt; \n17:21:58 SQL&gt; DECLARE\n  2    reginfo   CQ_NOTIFICATION$_REG_INFO;\n  3    v_cursor  SYS_REFCURSOR;\n  4    regid     NUMBER;\n  5  BEGIN\n  6    reginfo := cq_notification$_reg_info ( 'callback', DBMS_CHANGE_NOTIFICATION.QOS_ROWIDS, 0, 0, 0);\n  7    regid := sys.DBMS_CHANGE_NOTIFICATION.new_reg_start(reginfo);\n  8    OPEN v_cursor FOR\n  9      SELECT dbms_cq_notification.CQ_NOTIFICATION_QUERYID, demo.* from DEMO;\n 10    CLOSE v_cursor;\n 11    sys.DBMS_CHANGE_NOTIFICATION.reg_end;\n 12  END;\n 13  \/\n&nbsp;\nPL\/SQL procedure successfully completed.\n<\/code><\/pre>\n<p>Now I delete 1 million rows and commit:<\/p>\n<pre><code>\n17:21:58 SQL&gt; exec dbms_workload_repository.create_snapshot;\n&nbsp;\nPL\/SQL procedure successfully completed.\n&nbsp;\n17:22:02 SQL&gt; \n17:22:02 SQL&gt; -- 1000000 deletes\n17:22:02 SQL&gt; \n17:22:02 SQL&gt; exec for i in 1..1000000 loop delete from DEMO WHERE id=i; commit; end loop;\n&nbsp;\nPL\/SQL procedure successfully completed.\n&nbsp;\n17:39:23 SQL&gt; \n17:39:23 SQL&gt; exec dbms_workload_repository.create_snapshot;\n<\/code><\/pre>\n<p>Here are the notifications captured:<\/p>\n<pre><code>\n17:39:41 SQL&gt; select count(*) from notifications;\n  COUNT(*) \n  --------\n    942741 \n&nbsp;\n17:39:54 SQL&gt; select * from notifications fetch first 10 rows only;\n&nbsp;\n   ID MESSAGE                                       NOTIFICATION_DATE   \n  --- -------------------------------------------   -----------------\n  135 Table (DEMO.DEMO) - Records Deleted. Rows=1   09-MAY-18           \n  138 Table (DEMO.DEMO) - Records Deleted. Rows=1   09-MAY-18           \n  140 Table (DEMO.DEMO) - Records Deleted. Rows=1   09-MAY-18           \n  142 Table (DEMO.DEMO) - Records Deleted. Rows=1   09-MAY-18           \n  145 Table (DEMO.DEMO) - Records Deleted. Rows=1   09-MAY-18           \n  147 Table (DEMO.DEMO) - Records Deleted. Rows=1   09-MAY-18           \n  149 Table (DEMO.DEMO) - Records Deleted. Rows=1   09-MAY-18           \n  152 Table (DEMO.DEMO) - Records Deleted. Rows=1   09-MAY-18           \n  154 Table (DEMO.DEMO) - Records Deleted. Rows=1   09-MAY-18           \n  156 Table (DEMO.DEMO) - Records Deleted. Rows=1   09-MAY-18           \n<\/code><\/pre>\n<p>The DML has been long and SQL Monitoring shows that 64% of the time was waiting on &#8216;Wait for EMON to process ntfns&#8217; which is the notification process:<br \/>\n<a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN.png\" alt=\"CaptureCQN\" width=\"1024\" height=\"486\" class=\"aligncenter size-large wp-image-24929\" \/><\/a><\/p>\n<p>The execution of the delete itself (cdq5w65zk18r1 DELETE FROM DEMO WHERE ID=:B1) is only a small part of the database time. And we have additional load on the database:<br \/>\n<a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN01.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN01.png\" alt=\"CaptureCQN01\" width=\"1024\" height=\"503\" class=\"aligncenter size-large wp-image-24932\" \/><\/a><\/p>\n<p>The following is activity related to Continuous Query notification queuing of messages, the one that slows down the modifications, during the delete (from 17:22 to 17:38):<\/p>\n<pre><code>\n59p1yadp2g6mb\tcall DBMS_AQADM_SYS.REGISTER_DRIVER (  )\ngzf71xphapf1b\tselect  \/*+ INDEX(TAB AQ$_AQ_SRVNTFN_TABLE_1_I) *\/   tab.rowid, tab.msgid, tab.corrid, tab.priority, tab.delay,   tab.expiration ,tab.retry_count, tab.exception_qschema,   tab.exception_queue, tab.chain_no, tab.local_order_no, tab.enq_time,   tab.time_manager_info, tab.state, tab.enq_tid, tab.step_no,   tab.sender_name, tab.sender_address, tab.sender_protocol,   tab.dequeue_msgid, tab.user_prop, tab.user_data   from \"SYS\".\"AQ_SRVNTFN_TABLE_1\" tab  where q_name = :1 and (state = :2  )  order by q_name, state, enq_time, step_no, chain_no, local_order_no for update skip locked\n61cgh171qq5m6   delete \/*+ CACHE_CB(\"AQ_SRVNTFN_TABLE_1\") *\/ from \"SYS\".\"AQ_SRVNTFN_TABLE_1\" where rowid = :1\nccrv58ajb7pxg   begin callback(ntfnds =&gt; :1); end;\ncdq5w65zk18r1   DELETE FROM DEMO WHERE ID=:B1\n<\/code><\/pre>\n<p>And at the end (17:38), when the modifications are committed, my callback function is running to process the messages:<br \/>\n<a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN02.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN02.png\" alt=\"CaptureCQN02\" width=\"1024\" height=\"438\" class=\"aligncenter size-large wp-image-24934\" \/><\/a><br \/>\nthe main query is the insert from the callback function:<\/p>\n<pre><code>8z4m5tw9uh02d   INSERT INTO NOTIFICATIONS (ID, MESSAGE, NOTIFICATION_DATE) VALUES (NOTIFICATIONS_SEQ.NEXTVAL, :B1 , SYSDATE)<\/code><\/pre>\n<p>The callback function may send the changes to another system, rather than inserting them here, but then you can question the availability and, anyway, this will still have a high overhead in context switches and network roundtrips.<\/p>\n<p>In summary, for 1 million rows deleted, here are the queries that have been executed 1 million times:<\/p>\n<pre><code>\n                                             Elapsed\n Executions   Rows Processed  Rows per Exec   Time (s)  %CPU   %IO    SQL Id\n------------ --------------- -------------- ---------- ----- ----- -------------\n   1,000,000       1,000,000            1.0      123.4  55.2   3.2 cdq5w65zk18r1 Module: java@VM188 (TNS V1-V3) DELETE FROM DEMO WHERE ID=:B1\n     999,753         999,753            1.0      261.5  88.6    .7 dw9yv631knnqd                                insert into \"SYS\".\"AQ_SRVNTFN_TABLE_1\" (q_name, msgid, corrid, priority, state, delay, expiration, time_manager_info, local_order_no, chain_no, enq_time, step_no, enq_uid, enq_tid, retry_count, exception_qschema, exception_queue, recipient_key, dequeue_msgid, user_data, sender_name, sender_address, sender_protoc\n     978,351         978,351            1.0      212.5  64.3     0 61cgh171qq5m6 Module: DBMS_SCHEDULER         delete \/*+ CACHE_CB(\"AQ_SRVNTFN_TABLE_1\") *\/ from \"SYS\".\"AQ_SRVNTFN_TABLE_1\" where rowid = :1\n     978,248         942,657            1.0      971.6    20    .7 8z4m5tw9uh02d Module: DBMS_SCHEDULER         INSERT INTO NOTIFICATIONS (ID, MESSAGE, NOTIFICATION_DATE) VALUES (NOTIFICATIONS_SEQ.NEXTVAL, :B1 , SYSDATE)\n     978,167         942,559            1.0    1,178.7  33.1    .5 ccrv58ajb7pxg Module: DBMS_SCHEDULER         begin callback(ntfnds =&gt; :1); end;\n     977,984         977,809            1.0       73.9  96.5     0 brq600g3299zp Module: DBMS_SCHEDULER         SELECT INSTANCE_NUMBER FROM SYS.V$INSTANCE\n     933,845         978,350            1.0      446.9  51.4    .7 gzf71xphapf1b Module: DBMS_SCHEDULER         select \/*+ INDEX(TAB AQ$_AQ_SRVNTFN_TABLE_1_I) *\/ tab.rowid, tab.msgid, tab.corrid, tab.priority, tab.delay, tab.expiration ,tab.retry_count, tab.exception_qschema, tab.exception_queue, tab.chain_no, tab.local_order_no, tab.enq_time, tab.time_manager_info, tab.state, tab.enq_tid, tab.step_no, tab.sender_name\n<\/code><\/pre>\n<p>This is a huge overhead. And all this has generated 8 millions of redo entries. <\/p>\n<p>In summary, just forget about CQN to stream changes. This feature is aimed at cache refresh for rarely changing data. What we call today &#8216;event sourcing&#8217; exists for a long time in the database, with redo logs. When a user executes some DML, Oracle generates the redo records first, store them and apply them to update the current version of the table rows. And the redo logs keeps the atomicity of transaction (the &#8216;A&#8217; in ACID). Then better use this if the changes need to be propagated to other systems.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>By Franck Pachot . We are in an era where software architects want to stream the transactions out of the database and distribute them, as events, to multiple microservices. Don&#8217;t ask why, but that&#8217;s the trend: store inconsistent eventually consistent copies of data in different physical components, rather than simply using logical views in the [&hellip;]<\/p>\n","protected":false},"author":27,"featured_media":11390,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[59],"tags":[1387,1388,1389,1390,96],"type_dbi":[],"class_list":["post-11389","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","tag-continuous-query-notification","tag-cqn","tag-cqrs","tag-event-sourcing","tag-oracle"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Event Sourcing: CQN is not a replacement for CDC - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Event Sourcing: CQN is not a replacement for CDC\" \/>\n<meta property=\"og:description\" content=\"By Franck Pachot . We are in an era where software architects want to stream the transactions out of the database and distribute them, as events, to multiple microservices. Don&#8217;t ask why, but that&#8217;s the trend: store inconsistent eventually consistent copies of data in different physical components, rather than simply using logical views in the [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-07-02T19:02:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1901\" \/>\n\t<meta property=\"og:image:height\" content=\"903\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Oracle Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Oracle Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/\"},\"author\":{\"name\":\"Oracle Team\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\"},\"headline\":\"Event Sourcing: CQN is not a replacement for CDC\",\"datePublished\":\"2018-07-02T19:02:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/\"},\"wordCount\":680,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN.png\",\"keywords\":[\"Continuous Query Notification\",\"CQN\",\"CQRS\",\"Event Sourcing\",\"Oracle\"],\"articleSection\":[\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/\",\"name\":\"Event Sourcing: CQN is not a replacement for CDC - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN.png\",\"datePublished\":\"2018-07-02T19:02:43+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#primaryimage\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN.png\",\"contentUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN.png\",\"width\":1901,\"height\":903},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Event Sourcing: CQN is not a replacement for CDC\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\",\"name\":\"Oracle Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"caption\":\"Oracle Team\"},\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/oracle-team\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Event Sourcing: CQN is not a replacement for CDC - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/","og_locale":"en_US","og_type":"article","og_title":"Event Sourcing: CQN is not a replacement for CDC","og_description":"By Franck Pachot . We are in an era where software architects want to stream the transactions out of the database and distribute them, as events, to multiple microservices. Don&#8217;t ask why, but that&#8217;s the trend: store inconsistent eventually consistent copies of data in different physical components, rather than simply using logical views in the [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/","og_site_name":"dbi Blog","article_published_time":"2018-07-02T19:02:43+00:00","og_image":[{"width":1901,"height":903,"url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN.png","type":"image\/png"}],"author":"Oracle Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Oracle Team","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/"},"author":{"name":"Oracle Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee"},"headline":"Event Sourcing: CQN is not a replacement for CDC","datePublished":"2018-07-02T19:02:43+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/"},"wordCount":680,"commentCount":0,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN.png","keywords":["Continuous Query Notification","CQN","CQRS","Event Sourcing","Oracle"],"articleSection":["Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/","url":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/","name":"Event Sourcing: CQN is not a replacement for CDC - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN.png","datePublished":"2018-07-02T19:02:43+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN.png","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/CaptureCQN.png","width":1901,"height":903},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/event-sourcing-cqn-is-not-a-replacement-for-cdc\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Event Sourcing: CQN is not a replacement for CDC"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee","name":"Oracle Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","caption":"Oracle Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/oracle-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/11389","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=11389"}],"version-history":[{"count":0,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/11389\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media\/11390"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=11389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=11389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=11389"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=11389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}