<li>Startup the CAP with the .NET Core 2.1 BackgroundService. <aclass="magiclink magiclink-github magiclink-issue"href="https://github.com/dotnetcore/cap/issues/265"title="GitHub Issue: dotnetcore/cap#265">#265</a></li>
<li>Startup the CAP with the .NET Core 2.1 BackgroundService. (<aclass="magiclink magiclink-github magiclink-issue"href="https://github.com/dotnetcore/cap/issues/265"title="GitHub Issue: dotnetcore/cap#265">#265</a>)</li>
<li>Supported version options. (<aclass="magiclink magiclink-github magiclink-issue"href="https://github.com/dotnetcore/cap/issues/220"title="GitHub Issue: dotnetcore/cap#220">#220</a>)</li>
<li>Upgrade nuget package to .net core 2.2.</li>
</ul>
<p><strong>Breaking Changes:</strong></p>
<p>In order to support the "version isolation" feature, we introduced a new version field in version 2.4.0 to isolate different versions of the message, so this requires some adjustments to the database table structure. You can use the following SQL to add a version field to your database CAP related table.</p>
<li>Fixed different groups of the same topic name in one instance will cause routing bug. (<aclass="magiclink magiclink-github magiclink-issue"href="https://github.com/dotnetcore/cap/issues/235"title="GitHub Issue: dotnetcore/cap#235">#235</a>)</li>
<li>Fixed RabbitMQ topic name contains numbers will cause exception bug. (<aclass="magiclink magiclink-github magiclink-issue"href="https://github.com/dotnetcore/cap/issues/181"title="GitHub Issue: dotnetcore/cap#181">#181</a>)</li>
<p>In this version, we made some breaking changes for the publisher API, you can see this blog to understand the story behind.</p>
<p>If you have any migration question, please comment in issue <aclass="magiclink magiclink-github magiclink-issue"href="https://github.com/dotnetcore/cap/issues/190"title="GitHub Issue: dotnetcore/cap#190">#190</a>.</p>
<p><strong>Breaking Changes:</strong></p>
<ul>
<li>Removed app.UseCap() from Startup.cs</li>
<li>Message table primary key data type has been modified to Bigint and non auto-Increment. (<aclass="magiclink magiclink-github magiclink-issue"href="https://github.com/dotnetcore/cap/issues/180"title="GitHub Issue: dotnetcore/cap#180">#180</a>)</li>
<li>Fix message still sent if transaction faild bug. (<aclass="magiclink magiclink-github magiclink-issue"href="https://github.com/dotnetcore/cap/issues/118"title="GitHub Issue: dotnetcore/cap#118">#118</a>)</li>
<li>Multiple events in one transaction. (<aclass="magiclink magiclink-github magiclink-issue"href="https://github.com/dotnetcore/cap/issues/171"title="GitHub Issue: dotnetcore/cap#171">#171</a>)</li>
5</pre></div></td><tdclass="code"><divclass="codehilite"><pre><span></span><spanclass="na">[CapSubscribe("xxx.services.foo", Group = "moduleA")]</span>
<p>CAP only has one interface,It is <codeclass="codehilite">ICapPublisher</code>, You can get its instance from the DI container and then call it.</p>
<p>CAP only has one interface,It is <codeclass="codehilite">ICapPublisher</code>, You can get its instance from the DI container and then call it.</p>
<h2id="publish-send">Publish & Send<aclass="headerlink"href="#publish-send"title="Permanent link">¶</a></h2>
<h2id="publish-send">Publish & Send<aclass="headerlink"href="#publish-send"title="Permanent link">¶</a></h2>
<p>You can use the <codeclass="codehilite">Publish<T></code> or <codeclass="codehilite">PublishAsync<T></code> methods defined in the <codeclass="codehilite">ICapPublisher</code> interface to send the event messages.</p>
<p>You can use the <codeclass="codehilite">Publish<T></code> or <codeclass="codehilite">PublishAsync<T></code> methods defined in the <codeclass="codehilite">ICapPublisher</code> interface to send the event messages.</p>
<p>In this overload method, <codeclass="codehilite">callbackName</code> is the callback name of the subscription method,when the consumption-side finished processing messages,CAP will return the processed result and also call the specified subscription method</p>
<p>In this overload method, <codeclass="codehilite">callbackName</code> is the callback name of the subscription method,when the consumption-side finished processing messages,CAP will return the processed result and also call the specified subscription method</p>
When you set the <codeclass="codehilite"><spanclass="n">autoCommit</span><spanclass="o">:</span><spanclass="kc">false</span></code>, you can put your business logic before or after the Publish logic,the only thing you need to do is to ensure that they are in the same transaction.</p>
When you set the <codeclass="codehilite"><spanclass="n">autoCommit</span><spanclass="o">:</span><spanclass="kc">false</span></code>, you can put your business logic before or after the Publish logic,the only thing you need to do is to ensure that they are in the same transaction.</p>
<p>If you set the <codeclass="codehilite"><spanclass="n">autoCommit</span><spanclass="o">:</span><spanclass="kc">true</span></code>, you need publish message <codeclass="codehilite">_capBus.Publish</code> at the last.</p>
<p>If you set the <codeclass="codehilite"><spanclass="n">autoCommit</span><spanclass="o">:</span><spanclass="kc">true</span></code>, you need publish message <codeclass="codehilite">_capBus.Publish</code> at the last.</p>
<p>During the course,the message content will be serialized as json and stored in the message table.</p>
<p>During the course,the message content will be serialized as json and stored in the message table.</p>
You can also use multiple <codeclass="codehilite">CapSubscribe[""]</code> to decorate a method so that you can subscribe messages from different sources accordingly.</p>
You can also use multiple <codeclass="codehilite">CapSubscribe[""]</code> to decorate a method so that you can subscribe messages from different sources accordingly.</p>
<codeclass="codehilite">xxx.services.bar</code> is the name of the message to be subscribed.And it has different name in different message queque Clients.for example,in kafka the name is called Topic Name and in RAbbitMQ it is called RouteKey.</p>
<codeclass="codehilite">xxx.services.bar</code> is the name of the message to be subscribed.And it has different name in different message queque Clients.for example,in kafka the name is called Topic Name and in RAbbitMQ it is called RouteKey.</p>
<p>In RabbitMQ you can use regular expression in RouteKey:
<p>In RabbitMQ you can use regular expression in RouteKey:
<blockquote>
<blockquote>
...
@@ -955,12 +1024,17 @@ You can also use multiple <code class="codehilite">CapSubscribe[""]</c
...
@@ -955,12 +1024,17 @@ You can also use multiple <code class="codehilite">CapSubscribe[""]</c
<p><strong>Group</strong> is a collection of subscribers,each group can have one or multiple consumers,but a subscriber can only belongs to a certain group(you can not put a subscriber into multiple groups).Messages subscribed by members in a certain group can only be consumed once.</p>
<p><strong>Group</strong> is a collection of subscribers,each group can have one or multiple consumers,but a subscriber can only belongs to a certain group(you can not put a subscriber into multiple groups).Messages subscribed by members in a certain group can only be consumed once.</p>
<p>If you do not specify any group when subscribing,CAP will put the subscriber into a default group named <codeclass="codehilite">cap.default.group</code></p>
<p>If you do not specify any group when subscribing,CAP will put the subscriber into a default group named <codeclass="codehilite">cap.default.group</code></p>
<p>the following is a demo shows how to use group when subscribing.</p>
<p>the following is a demo shows how to use group when subscribing.</p>
<divclass="codehilite"><pre><span></span><spanclass="na">[CapSubscribe("xxx.services.foo", Group = "moduleA")]</span>
5</pre></div></td><tdclass="code"><divclass="codehilite"><pre><span></span><spanclass="na">[CapSubscribe("xxx.services.foo", Group = "moduleA")]</span>
<ahref="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/configuration.md"title="Edit this page"class="md-icon md-content__icon"></a>
<ahref="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/configuration.md"title="Edit this page"class="md-icon md-content__icon"></a>
<p><codeclass="codehilite">CapOptions</code> provides the following configuration items::</p>
<p><codeclass="codehilite">CapOptions</code> provides the following configuration items::</p>
<table>
<table>
...
@@ -840,14 +833,19 @@
...
@@ -840,14 +833,19 @@
</table>
</table>
<p>CapOptions provides a callback function for <codeclass="codehilite">FailedCallback</code> to handle failed messages. When the message fails to be sent multiple times, the CAP will mark the message state as <codeclass="codehilite">Failed</code>. The CAP has a special handler to handle this failed message. The failed message will be put back into the queue and sent to MQ. Prior to this, if <codeclass="codehilite">FailedCallback</code> has a value, this callback function will be called first to tell the client.</p>
<p>CapOptions provides a callback function for <codeclass="codehilite">FailedCallback</code> to handle failed messages. When the message fails to be sent multiple times, the CAP will mark the message state as <codeclass="codehilite">Failed</code>. The CAP has a special handler to handle this failed message. The failed message will be put back into the queue and sent to MQ. Prior to this, if <codeclass="codehilite">FailedCallback</code> has a value, this callback function will be called first to tell the client.</p>
<p>The type of FailedCallback is <codeclass="codehilite">Action<MessageType,string,string></code>. The first parameter is the message type (send or receive), the second parameter is the name of the message, and the third parameter is the content of the message.</p>
<p>The type of FailedCallback is <codeclass="codehilite">Action<MessageType,string,string></code>. The first parameter is the message type (send or receive), the second parameter is the name of the message, and the third parameter is the content of the message.</p>
<p>The CAP uses the CapOptions extension to implement the RabbitMQ configuration function. Therefore, the configuration of the RabbitMQ is used as follows:</p>
<p>The CAP uses the CapOptions extension to implement the RabbitMQ configuration function. Therefore, the configuration of the RabbitMQ is used as follows:</p>
<p><codeclass="codehilite">KafkaOptions</code> provides Kafka-related configurations. Because Kafka has more configurations, the MainConfig dictionary provided here is used to support custom configurations. You can check here to get support information for configuration items.</p>
<p><codeclass="codehilite">KafkaOptions</code> provides Kafka-related configurations. Because Kafka has more configurations, the MainConfig dictionary provided here is used to support custom configurations. You can check here to get support information for configuration items.</p>
<p>If you are using Entityframework as a message persistence store, then you can customize some configuration when configuring the CAP EntityFramework configuration item.</p>
<p>If you are using Entityframework as a message persistence store, then you can customize some configuration when configuring the CAP EntityFramework configuration item.</p>
<p>Note that if you use the <codeclass="codehilite">UseEntityFramework</code> configuration item, then you do not need to reconfigure the following sections for several different database configurations. The CAP will automatically read the database configuration information used in DbContext.</p>
<p>Note that if you use the <codeclass="codehilite">UseEntityFramework</code> configuration item, then you do not need to reconfigure the following sections for several different database configurations. The CAP will automatically read the database configuration information used in DbContext.</p>
<ahref="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/design-principle.md"title="Edit this page"class="md-icon md-content__icon"></a>
<ahref="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/design.md"title="Edit this page"class="md-icon md-content__icon"></a>
<p>With the popularity of microservices architecture, more and more people are trying to use microservices to architect their systems. In this we encounter problems such as distributed transactions. To solve these problems, I did not find simplicity and Easy to use solution, so I decided to create such a library to solve this problem.</p>
<p>With the popularity of microservices architecture, more and more people are trying to use microservices to architect their systems. In this we encounter problems such as distributed transactions. To solve these problems, I did not find simplicity and Easy to use solution, so I decided to create such a library to solve this problem.</p>
<p>The original CAP was to solve the transaction problems in the distributed system. She used asynchronous to ensure that this weak consistency transaction mechanism achieved the eventual consistency of the distributed transaction. For more information, see section 6.</p>
<p>The original CAP was to solve the transaction problems in the distributed system. She used asynchronous to ensure that this weak consistency transaction mechanism achieved the eventual consistency of the distributed transaction. For more information, see section 6.</p>
<p>Now in addition to solving distributed transaction problems, CAP's other important function is to use it as an EventBus. It has all of the features of EventBus and provides a more simplified way to handle publish/subscribe in EventBus.</p>
<p>Now in addition to solving distributed transaction problems, CAP's other important function is to use it as an EventBus. It has all of the features of EventBus and provides a more simplified way to handle publish/subscribe in EventBus.</p>
<p>The CAP relies on the local database for persistence of messages. The CAP uses this method to deal with situations in which all messages are lost due to environmental or network anomalies. The reliability of messages is the cornerstone of distributed transactions, so messages cannot be lost under any circumstances.</p>
<p>The CAP relies on the local database for persistence of messages. The CAP uses this method to deal with situations in which all messages are lost due to environmental or network anomalies. The reliability of messages is the cornerstone of distributed transactions, so messages cannot be lost under any circumstances.</p>
<p>There are two types of persistence for messages:</p>
<p>There are two types of persistence for messages:</p>
<p><strong>1 Persistence before the message enters the message queue</strong></p>
<p><strong>1 Persistence before the message enters the message queue</strong></p>
...
@@ -759,7 +737,7 @@
...
@@ -759,7 +737,7 @@
<p>After the message enters the message queue, the CAP starts the persistence function of the message queue. We need to explain how the message of the CAP in RabbitMQ and Kafka is persistent.</p>
<p>After the message enters the message queue, the CAP starts the persistence function of the message queue. We need to explain how the message of the CAP in RabbitMQ and Kafka is persistent.</p>
<p>For message persistence in RabbitMQ, CAP uses a consumer queue with message persistence, but there may be exceptions to this and take part in 2.2.1.</p>
<p>For message persistence in RabbitMQ, CAP uses a consumer queue with message persistence, but there may be exceptions to this and take part in 2.2.1.</p>
<p>Since Kafka is inherently designed to persist messages using files, Kafka ensures that messages are correctly persisted without loss after the message enters Kafka.</p>
<p>Since Kafka is inherently designed to persist messages using files, Kafka ensures that messages are correctly persisted without loss after the message enters Kafka.</p>
<h3id="communication-data-streams">Communication Data Streams<aclass="headerlink"href="#communication-data-streams"title="Permanent link">¶</a></h3>
<h2id="communication-data-streams">Communication Data Streams<aclass="headerlink"href="#communication-data-streams"title="Permanent link">¶</a></h2>
<p>The flow of messages in the CAP is roughly as follows:</p>
<p>The flow of messages in the CAP is roughly as follows:</p>
<p>In the 2.2 and later versions, we adjusted the flow of some messages. We removed the Queue table in the database and used the memory queue instead. For details, see: <ahref="https://github.com/dotnetcore/CAP/issues/96">Improve the implementation mechanism of queue mode</a></p>
<p>In the 2.2 and later versions, we adjusted the flow of some messages. We removed the Queue table in the database and used the memory queue instead. For details, see: <ahref="https://github.com/dotnetcore/CAP/issues/96">Improve the implementation mechanism of queue mode</a></p>
<p>The CAP uses the ultimate consistency as a consistent solution. This solution follows the CAP theory. The following is the description of the CAP theory.</p>
<p>The CAP uses the ultimate consistency as a consistent solution. This solution follows the CAP theory. The following is the description of the CAP theory.</p>
<p>C (consistent) consistency refers to the atomicity of data. It is guaranteed by transactions in a classic database. When a transaction completes, the data will be in a consistent state regardless of success or rollback. In a distributed environment, consistency is Indicates whether the data of multiple nodes is consistent;</p>
<p>C (consistent) consistency refers to the atomicity of data. It is guaranteed by transactions in a classic database. When a transaction completes, the data will be in a consistent state regardless of success or rollback. In a distributed environment, consistency is Indicates whether the data of multiple nodes is consistent;</p>
<p>A (availability) service is always available, when the user sends a request, the service can return the result within a certain time;</p>
<p>A (availability) service is always available, when the user sends a request, the service can return the result within a certain time;</p>
<labelclass="md-nav__title"for="__toc">Table of contents</label>
<labelclass="md-nav__title"for="__toc">Table of contents</label>
<ulclass="md-nav__list"data-md-scrollfix>
<ulclass="md-nav__list"data-md-scrollfix>
<liclass="md-nav__item">
<liclass="md-nav__item">
<ahref="#faq"title="FAQ"class="md-nav__link">
FAQ
</a>
<navclass="md-nav">
<ulclass="md-nav__list">
<liclass="md-nav__item">
<ahref="#any-im-groupeg-tencent-qq-group-to-learn-and-chat-about-cap"title="Any IM group(e.g Tencent QQ group) to learn and chat about CAP?"class="md-nav__link">
<ahref="#any-im-groupeg-tencent-qq-group-to-learn-and-chat-about-cap"title="Any IM group(e.g Tencent QQ group) to learn and chat about CAP?"class="md-nav__link">
Any IM group(e.g Tencent QQ group) to learn and chat about CAP?
Any IM group(e.g Tencent QQ group) to learn and chat about CAP?
</a>
</a>
</li>
</li>
<liclass="md-nav__item">
<liclass="md-nav__item">
<ahref="#does-it-require-certain-different-databases-one-each-for-productor-and-resumer-in-cap"title="Does it require certain different databases, one each for productor and resumer in CAP?"class="md-nav__link">
<ahref="#does-it-require-certain-different-databases-one-each-for-productor-and-resumer-in-cap"title="Does it require certain different databases, one each for productor and resumer in CAP?"class="md-nav__link">
Does it require certain different databases, one each for productor and resumer in CAP?
Does it require certain different databases, one each for productor and resumer in CAP?
</a>
</a>
</li>
</li>
<liclass="md-nav__item">
<liclass="md-nav__item">
<ahref="#how-to-use-the-same-database-for-different-programs"title="How to use the same database for different programs?"class="md-nav__link">
<ahref="#how-to-use-the-same-database-for-different-programs"title="How to use the same database for different programs?"class="md-nav__link">
How to use the same database for different programs?
How to use the same database for different programs?
</a>
</a>
</li>
</li>
<liclass="md-nav__item">
<liclass="md-nav__item">
<ahref="#if-dont-care-about-message-missing-can-message-productor-exist-without-any-database-for-the-reason-of-sending-message-only"title="If don't care about message missing, can message productor exist without any database, for the reason of sending message only."class="md-nav__link">
<ahref="#if-dont-care-about-message-missing-can-message-productor-exist-without-any-database-for-the-reason-of-sending-message-only"title="If don't care about message missing, can message productor exist without any database, for the reason of sending message only."class="md-nav__link">
If don't care about message missing, can message productor exist without any database, for the reason of sending message only.
If don't care about message missing, can message productor exist without any database, for the reason of sending message only.
</a>
</a>
</li>
</li>
</ul>
</nav>
</li>
...
@@ -678,50 +669,39 @@
...
@@ -678,50 +669,39 @@
<navclass="md-nav md-nav--secondary">
<navclass="md-nav md-nav--secondary">
<labelclass="md-nav__title"for="__toc">Table of contents</label>
<labelclass="md-nav__title"for="__toc">Table of contents</label>
<ulclass="md-nav__list"data-md-scrollfix>
<ulclass="md-nav__list"data-md-scrollfix>
<liclass="md-nav__item">
<liclass="md-nav__item">
<ahref="#faq"title="FAQ"class="md-nav__link">
FAQ
</a>
<navclass="md-nav">
<ulclass="md-nav__list">
<liclass="md-nav__item">
<ahref="#any-im-groupeg-tencent-qq-group-to-learn-and-chat-about-cap"title="Any IM group(e.g Tencent QQ group) to learn and chat about CAP?"class="md-nav__link">
<ahref="#any-im-groupeg-tencent-qq-group-to-learn-and-chat-about-cap"title="Any IM group(e.g Tencent QQ group) to learn and chat about CAP?"class="md-nav__link">
Any IM group(e.g Tencent QQ group) to learn and chat about CAP?
Any IM group(e.g Tencent QQ group) to learn and chat about CAP?
</a>
</a>
</li>
</li>
<liclass="md-nav__item">
<liclass="md-nav__item">
<ahref="#does-it-require-certain-different-databases-one-each-for-productor-and-resumer-in-cap"title="Does it require certain different databases, one each for productor and resumer in CAP?"class="md-nav__link">
<ahref="#does-it-require-certain-different-databases-one-each-for-productor-and-resumer-in-cap"title="Does it require certain different databases, one each for productor and resumer in CAP?"class="md-nav__link">
Does it require certain different databases, one each for productor and resumer in CAP?
Does it require certain different databases, one each for productor and resumer in CAP?
</a>
</a>
</li>
</li>
<liclass="md-nav__item">
<liclass="md-nav__item">
<ahref="#how-to-use-the-same-database-for-different-programs"title="How to use the same database for different programs?"class="md-nav__link">
<ahref="#how-to-use-the-same-database-for-different-programs"title="How to use the same database for different programs?"class="md-nav__link">
How to use the same database for different programs?
How to use the same database for different programs?
</a>
</a>
</li>
</li>
<liclass="md-nav__item">
<liclass="md-nav__item">
<ahref="#if-dont-care-about-message-missing-can-message-productor-exist-without-any-database-for-the-reason-of-sending-message-only"title="If don't care about message missing, can message productor exist without any database, for the reason of sending message only."class="md-nav__link">
<ahref="#if-dont-care-about-message-missing-can-message-productor-exist-without-any-database-for-the-reason-of-sending-message-only"title="If don't care about message missing, can message productor exist without any database, for the reason of sending message only."class="md-nav__link">
If don't care about message missing, can message productor exist without any database, for the reason of sending message only.
If don't care about message missing, can message productor exist without any database, for the reason of sending message only.
</a>
</a>
</li>
</li>
</ul>
</nav>
</li>
...
@@ -742,18 +722,27 @@
...
@@ -742,18 +722,27 @@
<ahref="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/faq.md"title="Edit this page"class="md-icon md-content__icon"></a>
<ahref="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/faq.md"title="Edit this page"class="md-icon md-content__icon"></a>
<h2id="any-im-groupeg-tencent-qq-group-to-learn-and-chat-about-cap">Any IM group(e.g Tencent QQ group) to learn and chat about CAP?<aclass="headerlink"href="#any-im-groupeg-tencent-qq-group-to-learn-and-chat-about-cap"title="Permanent link">¶</a></h2>
<h3id="any-im-groupeg-tencent-qq-group-to-learn-and-chat-about-cap">Any IM group(e.g Tencent QQ group) to learn and chat about CAP?<aclass="headerlink"href="#any-im-groupeg-tencent-qq-group-to-learn-and-chat-about-cap"title="Permanent link">¶</a></h3>
<p>None for that. Better than wasting much time in IM group, I hope developers could be capable of independent thinking more, and solve problems yourselves with referenced documents, even create issues or send emails when errors are remaining present.</p>
<p>None for that. Better than wasting much time in IM group, I hope developers could be capable of independent thinking more, and solve problems yourselves with referenced documents, even create issues or send emails when errors are remaining present.</p>
<h3id="does-it-require-certain-different-databases-one-each-for-productor-and-resumer-in-cap">Does it require certain different databases, one each for productor and resumer in CAP?<aclass="headerlink"href="#does-it-require-certain-different-databases-one-each-for-productor-and-resumer-in-cap"title="Permanent link">¶</a></h3>
<h2id="does-it-require-certain-different-databases-one-each-for-productor-and-resumer-in-cap">Does it require certain different databases, one each for productor and resumer in CAP?<aclass="headerlink"href="#does-it-require-certain-different-databases-one-each-for-productor-and-resumer-in-cap"title="Permanent link">¶</a></h2>
<p>Not requird differences necessary, a given advice is that using a special database for each program.</p>
<p>Not requird differences necessary, a given advice is that using a special database for each program.</p>
<p>Otherwise, look at Q&A below.</p>
<p>Otherwise, look at Q&A below.</p>
<h3id="how-to-use-the-same-database-for-different-programs">How to use the same database for different programs?<aclass="headerlink"href="#how-to-use-the-same-database-for-different-programs"title="Permanent link">¶</a></h3>
<h2id="how-to-use-the-same-database-for-different-programs">How to use the same database for different programs?<aclass="headerlink"href="#how-to-use-the-same-database-for-different-programs"title="Permanent link">¶</a></h2>
<p>defining a prefix name of table in <codeclass="codehilite">ConfigureServices</code> method。</p>
<p>defining a prefix name of table in <codeclass="codehilite">ConfigureServices</code> method。</p>
<p>NOTE:different prefixed names cause SLB to no effect.</p>
<divclass="admonition note">
<h3id="if-dont-care-about-message-missing-can-message-productor-exist-without-any-database-for-the-reason-of-sending-message-only">If don't care about message missing, can message productor exist without any database, for the reason of sending message only.<aclass="headerlink"href="#if-dont-care-about-message-missing-can-message-productor-exist-without-any-database-for-the-reason-of-sending-message-only"title="Permanent link">¶</a></h3>
<pclass="admonition-title">Note</p>
<p>Different prefixed names cause SLB to no effect.</p>
</div>
<h2id="if-dont-care-about-message-missing-can-message-productor-exist-without-any-database-for-the-reason-of-sending-message-only">If don't care about message missing, can message productor exist without any database, for the reason of sending message only.<aclass="headerlink"href="#if-dont-care-about-message-missing-can-message-productor-exist-without-any-database-for-the-reason-of-sending-message-only"title="Permanent link">¶</a></h2>
<p>Not yet.</p>
<p>Not yet.</p>
<p>The purpose of CAP is that ensure consistency principle right in microservice or SOA architechtrues. The solution is based on ACID features of database, there is no sense about a single client wapper of message queue without database.</p>
<p>The purpose of CAP is that ensure consistency principle right in microservice or SOA architechtrues. The solution is based on ACID features of database, there is no sense about a single client wapper of message queue without database.</p>
<ahref="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/getting-started.md"title="Edit this page"class="md-icon md-content__icon"></a>
<ahref="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/getting-started.md"title="Edit this page"class="md-icon md-content__icon"></a>
<p>CAP is a library based on .Net standard, which is a solution to deal with distributed transactions, also has the function of EventBus, it is lightweight, easy to use, and efficiently.</p>
<p>In an ASP.NET Core program, you can configure the services used by the CAP in the <codeclass="codehilite">Startup.cs</code> file <codeclass="codehilite">ConfigureServices()</code>:</p>
<p>In an ASP.NET Core program, you can configure the services used by the CAP in the <codeclass="codehilite">Startup.cs</code> file <codeclass="codehilite">ConfigureServices()</code>:</p>
<p>Inject <codeclass="codehilite">ICapPublisher</code> in your Controller, then use the <codeclass="codehilite">ICapPublisher</code> to send message</p>
<p>Inject <codeclass="codehilite">ICapPublisher</code> in your Controller, then use the <codeclass="codehilite">ICapPublisher</code> to send message</p>
<ahref="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/implementation-mechanisms.md"title="Edit this page"class="md-icon md-content__icon"></a>
<ahref="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/implementation.md"title="Edit this page"class="md-icon md-content__icon"></a>
<h1>Implementation Mechanisms</h1>
<p>Users can get a ICapPublisher interface from the ASP.NET Core DI container to publish a message .It is initialized by configurations in the <codeclass="codehilite">ConfigureServices</code> and <codeclass="codehilite">configure</code> method in the Startup.cs file,just like the way to initialize a <codeclass="codehilite">MiddleWare</code> in ASP.NET Core.</p>
<p>Users can get a ICapPublisher interface from the ASP.NET Core DI container to publish a message .It is initialized by configurations in the <codeclass="codehilite">ConfigureServices</code> and <codeclass="codehilite">configure</code> method in the Startup.cs file,just like the way to initialize a <codeclass="codehilite">MiddleWare</code> in ASP.NET Core.</p>
<p>After initialized, CAP will create two tables in the client side,they are <codeclass="codehilite">Cap.Published</code> and <codeclass="codehilite">Cap.Received</code>. Please noted that different databases may deal letter case differently,if you do not explicitly specify the Schema or the TableName Prefix before project startup,the default names are the ones mentioned above.</p>
<p>After initialized, CAP will create two tables in the client side,they are <codeclass="codehilite">Cap.Published</code> and <codeclass="codehilite">Cap.Received</code>. Please noted that different databases may deal letter case differently,if you do not explicitly specify the Schema or the TableName Prefix before project startup,the default names are the ones mentioned above.</p>
<p><strong>Cap.Published</strong>:Used to store messages(Published by the <codeclass="codehilite">ICapPublisher</code> service) that CAP published to the MQ(Message Queue)Client side</p>
<p><strong>Cap.Published</strong>:Used to store messages(Published by the <codeclass="codehilite">ICapPublisher</code> service) that CAP published to the MQ(Message Queue)Client side</p>
<p><strong>Cap.Received</strong>:Used to Store messages(subscribed by the <codeclass="codehilite">CapSubscribe[]</code>) subscribed by the MQ(message Queue) client side that CAP received.</p>
<p><strong>Cap.Received</strong>:Used to Store messages(subscribed by the <codeclass="codehilite">CapSubscribe[]</code>) subscribed by the MQ(message Queue) client side that CAP received.</p>
...
@@ -750,7 +755,7 @@
...
@@ -750,7 +755,7 @@
<blockquote>
<blockquote>
<p>Before version 2.2,CAP retry 100 times for <codeclass="codehilite">Failed</code> messages by default.</p>
<p>Before version 2.2,CAP retry 100 times for <codeclass="codehilite">Failed</code> messages by default.</p>
<p>EventBus adopt the publish-subscribe messaging style to communicate with different components,and there is no need to register it in component explicitly.</p>
<p>EventBus adopt the publish-subscribe messaging style to communicate with different components,and there is no need to register it in component explicitly.</p>
<p>the diagram in the above link shows Eventbus's event flowchart,about EventBus,users can refer to other meterials to learn about it.</p>
<p>the diagram in the above link shows Eventbus's event flowchart,about EventBus,users can refer to other meterials to learn about it.</p>
<p>We say that CAP implement all the features in Eventbus,EventBus has two features:publish and subscribe,In CAP we implement them in an elegant way.Besides,CAP also has two very robust feature,they are message persistence and messaging reliability under any circumstances,But EventBus don't have such features.</p>
<p>We say that CAP implement all the features in Eventbus,EventBus has two features:publish and subscribe,In CAP we implement them in an elegant way.Besides,CAP also has two very robust feature,they are message persistence and messaging reliability under any circumstances,But EventBus don't have such features.</p>
<p>In CAP,send a message can be regarded as an "Event",When CAP is used in an ASP.NET Core applicaiton,the application has the ablity to publish as well as receive messages.</p>
<p>In CAP,send a message can be regarded as an "Event",When CAP is used in an ASP.NET Core applicaiton,the application has the ablity to publish as well as receive messages.</p>
<p>Retry plays a very important role in CAP's infrastructure,CAP will retry for Failed messages.CAP has the following retry strategies:</p>
<p>Retry plays a very important role in CAP's infrastructure,CAP will retry for Failed messages.CAP has the following retry strategies:</p>
<p><strong>1、 Retry on sending</strong></p>
<p><strong>1、 Retry on sending</strong></p>
<p>in the process of sending a message,when the Broker crashed or connection failed or exceptions are thrown,CAP will retry,it will retry 3 times for the first time,if still failed,then it will retry every 1 minute,the retry the retry count +1,when the retry count come to 50,CAP will not retry any more.</p>
<p>in the process of sending a message,when the Broker crashed or connection failed or exceptions are thrown,CAP will retry,it will retry 3 times for the first time,if still failed,then it will retry every 1 minute,the retry the retry count +1,when the retry count come to 50,CAP will not retry any more.</p>
...
@@ -861,7 +866,7 @@
...
@@ -861,7 +866,7 @@
<p>As metioned above,when the retry count comes to a certain number,CAP will not retry anymore,this time,you can find out the fail reason in the Dashboard and they deal with it manually.</p>
<p>As metioned above,when the retry count comes to a certain number,CAP will not retry anymore,this time,you can find out the fail reason in the Dashboard and they deal with it manually.</p>
<p><strong>2、 Retry on Consuming</strong></p>
<p><strong>2、 Retry on Consuming</strong></p>
<p>When consumer received messages,specified method in the consumer will be executed,if exceptions are thrown during this course,CAP will retry,the retry strategy is the same as above <codeclass="codehilite">Retry on sending</code>.</p>
<p>When consumer received messages,specified method in the consumer will be executed,if exceptions are thrown during this course,CAP will retry,the retry strategy is the same as above <codeclass="codehilite">Retry on sending</code>.</p>
<p>table to store messages in database has an <codeclass="codehilite">ExpiresAt</code> field to mark the expiration time of the message. CAP will set <codeclass="codehilite">ExpiresAt</code> value as <strong>1 hour</strong> for <codeclass="codehilite">Successed</code> messages and <strong>15days</strong> for <codeclass="codehilite">Failed</code> messages.</p>
<p>table to store messages in database has an <codeclass="codehilite">ExpiresAt</code> field to mark the expiration time of the message. CAP will set <codeclass="codehilite">ExpiresAt</code> value as <strong>1 hour</strong> for <codeclass="codehilite">Successed</code> messages and <strong>15days</strong> for <codeclass="codehilite">Failed</code> messages.</p>
<p>To avoid performance slow down caused by a large amount of data,CAP will delete expired data every hour by default,the deletion rule is that <codeclass="codehilite">ExpiresAt</code> field's value isn't null and samller than current time.That is, <codeclass="codehilite">Failed</code> messages(it has been retried 50 times by default),if you do not deal with it manually,will also be deleted after 15 days as well,you have to pay attention to it.</p>
<p>To avoid performance slow down caused by a large amount of data,CAP will delete expired data every hour by default,the deletion rule is that <codeclass="codehilite">ExpiresAt</code> field's value isn't null and samller than current time.That is, <codeclass="codehilite">Failed</code> messages(it has been retried 50 times by default),if you do not deal with it manually,will also be deleted after 15 days as well,you have to pay attention to it.</p>
<labelclass="md-nav__title"for="__toc">Table of contents</label>
<labelclass="md-nav__title"for="__toc">Table of contents</label>
<ulclass="md-nav__list"data-md-scrollfix>
<ulclass="md-nav__list"data-md-scrollfix>
...
@@ -644,6 +648,8 @@
...
@@ -644,6 +648,8 @@
<navclass="md-nav md-nav--secondary">
<navclass="md-nav md-nav--secondary">
<labelclass="md-nav__title"for="__toc">Table of contents</label>
<labelclass="md-nav__title"for="__toc">Table of contents</label>
<ulclass="md-nav__list"data-md-scrollfix>
<ulclass="md-nav__list"data-md-scrollfix>
...
@@ -671,13 +677,12 @@
...
@@ -671,13 +677,12 @@
<articleclass="md-content__inner md-typeset">
<articleclass="md-content__inner md-typeset">
<ahref="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/distributed-transactions.md"title="Edit this page"class="md-icon md-content__icon"></a>
<ahref="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/transaction.md"title="Edit this page"class="md-icon md-content__icon"></a>
<h1>Distributed Transactions</h1>
<p>For the processing of distributed transactions, this CAP library matches the "Asynchronous recovery events" scenario.</p>
<p>As known as the name "native message table", this is a classic solution, originally from EBay, and referenced links about it are at the end of this section. This is also one of the most popular solutions in the business development. </p>
<p>As known as the name "native message table", this is a classic solution, originally from EBay, and referenced links about it are at the end of this section. This is also one of the most popular solutions in the business development. </p>
<p>Compared to TCC or 2pc/3pc, this solution is the simplest one for distributed transactions, and is decentralized. In TCC or 2PC solutions, the common transaction handlers synchronize the state among different services with a transaction coordinator, but it's not much required in this CAP solution. In addition, the deeper references of other conditions these services have, the more management complexity and stability risk may be increased in 2PC/TCC. Imagine that if we have 9 services committed successfully of all 10 whitch relied heavily, though the last one execute fail, should we roll back transactions of those 9 service? In fact, the cost is still very high. </p>
<p>Compared to TCC or 2pc/3pc, this solution is the simplest one for distributed transactions, and is decentralized. In TCC or 2PC solutions, the common transaction handlers synchronize the state among different services with a transaction coordinator, but it's not much required in this CAP solution. In addition, the deeper references of other conditions these services have, the more management complexity and stability risk may be increased in 2PC/TCC. Imagine that if we have 9 services committed successfully of all 10 whitch relied heavily, though the last one execute fail, should we roll back transactions of those 9 service? In fact, the cost is still very high. </p>
<p>However, it's not mean that 2PC or TCC are at a disadvantage, each has its own suitability and matched scenarios, here won't introduce more.</p>
<p>However, it's not mean that 2PC or TCC are at a disadvantage, each has its own suitability and matched scenarios, here won't introduce more.</p>