Commit b877aa78 authored by Savorboard's avatar Savorboard

Deployed c0a43b5f with MkDocs version: 1.0.4

parent 14d74eb1
...@@ -371,7 +371,7 @@ ...@@ -371,7 +371,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="user-guide/design-principle/" title="Design Principle" class="md-nav__link"> <a href="user-guide/design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -383,7 +383,7 @@ ...@@ -383,7 +383,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="user-guide/implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="user-guide/implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -395,7 +395,7 @@ ...@@ -395,7 +395,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="user-guide/distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="user-guide/transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
......
...@@ -379,7 +379,7 @@ ...@@ -379,7 +379,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/design-principle/" title="Design Principle" class="md-nav__link"> <a href="../../user-guide/design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -391,7 +391,7 @@ ...@@ -391,7 +391,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../../user-guide/implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -403,7 +403,7 @@ ...@@ -403,7 +403,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../../user-guide/transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -590,6 +590,8 @@ ...@@ -590,6 +590,8 @@
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc"> <input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc"> <label class="md-nav__link md-nav__link--active" for="__toc">
Contact Us Contact Us
...@@ -603,20 +605,22 @@ ...@@ -603,20 +605,22 @@
<nav class="md-nav md-nav--secondary"> <nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label> <label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#contact-us" title="Contact Us" class="md-nav__link"> <a href="#authors" title="Authors" class="md-nav__link">
Contact Us Authors
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#cap-team" title="CAP Team" class="md-nav__link"> <a href="#ncc-organization" title="NCC Organization" class="md-nav__link">
CAP Team NCC Organization
</a> </a>
</li> </li>
...@@ -651,20 +655,22 @@ ...@@ -651,20 +655,22 @@
<nav class="md-nav md-nav--secondary"> <nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label> <label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#contact-us" title="Contact Us" class="md-nav__link"> <a href="#authors" title="Authors" class="md-nav__link">
Contact Us Authors
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#cap-team" title="CAP Team" class="md-nav__link"> <a href="#ncc-organization" title="NCC Organization" class="md-nav__link">
CAP Team NCC Organization
</a> </a>
</li> </li>
...@@ -688,14 +694,19 @@ ...@@ -688,14 +694,19 @@
<a href="https://github.com/dotnetcore/cap/edit/master/docs/about/contact-us.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a> <a href="https://github.com/dotnetcore/cap/edit/master/docs/about/contact-us.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a>
<h1>Contact Us</h1> <h1 id="contact-us">Contact Us<a class="headerlink" href="#contact-us" title="Permanent link">&para;</a></h1>
<h2 id="authors">Authors<a class="headerlink" href="#authors" title="Permanent link">&para;</a></h2>
<h2 id="contact-us">Contact Us<a class="headerlink" href="#contact-us" title="Permanent link">&para;</a></h2>
<ul> <ul>
<li>Submit an issue</li> <li>Author: <a href="https://github.com/yang-xiaodong">@yang-xiaodong</a></li>
<li>Email: <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#121;&#97;&#110;&#103;&#120;&#105;&#97;&#111;&#100;&#111;&#110;&#103;&#49;&#50;&#49;&#52;&#64;&#49;&#50;&#54;&#46;&#99;&#111;&#109;">&#121;&#97;&#110;&#103;&#120;&#105;&#97;&#111;&#100;&#111;&#110;&#103;&#49;&#50;&#49;&#52;&#64;&#49;&#50;&#54;&#46;&#99;&#111;&#109;</a></li> <li>Email: <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#121;&#97;&#110;&#103;&#120;&#105;&#97;&#111;&#100;&#111;&#110;&#103;&#49;&#50;&#49;&#52;&#64;&#49;&#50;&#54;&#46;&#99;&#111;&#109;">&#121;&#97;&#110;&#103;&#120;&#105;&#97;&#111;&#100;&#111;&#110;&#103;&#49;&#50;&#49;&#52;&#64;&#49;&#50;&#54;&#46;&#99;&#111;&#109;</a></li>
<li>Blogs: <a href="https://saborboard.cnblogs.com">https://saborboard.cnblogs.com</a></li>
</ul>
<h2 id="ncc-organization">NCC Organization<a class="headerlink" href="#ncc-organization" title="Permanent link">&para;</a></h2>
<ul>
<li>Email: <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#100;&#111;&#116;&#110;&#101;&#116;&#99;&#110;&#64;&#111;&#117;&#116;&#108;&#111;&#111;&#107;&#46;&#99;&#111;&#109;">&#100;&#111;&#116;&#110;&#101;&#116;&#99;&#110;&#64;&#111;&#117;&#116;&#108;&#111;&#111;&#107;&#46;&#99;&#111;&#109;</a></li>
<li>Twitter: <a href="https://twitter.com/ncc_community">https://twitter.com/ncc_community</a></li>
<li>Weibo: <a href="https://weibo.com/dotnetcore">https://weibo.com/dotnetcore</a></li>
</ul> </ul>
<h2 id="cap-team">CAP Team<a class="headerlink" href="#cap-team" title="Permanent link">&para;</a></h2>
......
...@@ -108,6 +108,10 @@ ...@@ -108,6 +108,10 @@
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off"> <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label> <label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="#contributing" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header"> <header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid"> <nav class="md-header-nav md-grid">
...@@ -375,7 +379,7 @@ ...@@ -375,7 +379,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/design-principle/" title="Design Principle" class="md-nav__link"> <a href="../../user-guide/design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -387,7 +391,7 @@ ...@@ -387,7 +391,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../../user-guide/implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -399,7 +403,7 @@ ...@@ -399,7 +403,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../../user-guide/transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -574,6 +578,8 @@ ...@@ -574,6 +578,8 @@
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc"> <input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<a href="./" title="Contributing" class="md-nav__link md-nav__link--active"> <a href="./" title="Contributing" class="md-nav__link md-nav__link--active">
Contributing Contributing
...@@ -606,6 +612,21 @@ ...@@ -606,6 +612,21 @@
</div> </div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
</nav>
</div>
</div>
</div>
<div class="md-content"> <div class="md-content">
<article class="md-content__inner md-typeset"> <article class="md-content__inner md-typeset">
...@@ -614,9 +635,8 @@ ...@@ -614,9 +635,8 @@
<a href="https://github.com/dotnetcore/cap/edit/master/docs/about/contributing.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a> <a href="https://github.com/dotnetcore/cap/edit/master/docs/about/contributing.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a>
<h1>Contributing</h1> <h1 id="contributing">Contributing<a class="headerlink" href="#contributing" title="Permanent link">&para;</a></h1>
<p>Pull requests, issues and commentary welcome! No special process just create a request and get in touch either via gitter or create an issue.</p>
......
...@@ -379,7 +379,7 @@ ...@@ -379,7 +379,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/design-principle/" title="Design Principle" class="md-nav__link"> <a href="../../user-guide/design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -391,7 +391,7 @@ ...@@ -391,7 +391,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../../user-guide/implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -403,7 +403,7 @@ ...@@ -403,7 +403,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../../user-guide/transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -601,6 +601,27 @@ ...@@ -601,6 +601,27 @@
</li> </li>
<li class="md-nav__item">
<a href="#version-240-2018-12-08" title="Version 2.4.0 (2018-12-08)" class="md-nav__link">
Version 2.4.0 (2018-12-08)
</a>
</li>
<li class="md-nav__item">
<a href="#version-231-2018-10-29" title="Version 2.3.1 (2018-10-29)" class="md-nav__link">
Version 2.3.1 (2018-10-29)
</a>
</li>
<li class="md-nav__item">
<a href="#version-230-2018-08-30" title="Version 2.3.0 (2018-08-30)" class="md-nav__link">
Version 2.3.0 (2018-08-30)
</a>
</li>
...@@ -675,6 +696,27 @@ ...@@ -675,6 +696,27 @@
</li> </li>
<li class="md-nav__item">
<a href="#version-240-2018-12-08" title="Version 2.4.0 (2018-12-08)" class="md-nav__link">
Version 2.4.0 (2018-12-08)
</a>
</li>
<li class="md-nav__item">
<a href="#version-231-2018-10-29" title="Version 2.3.1 (2018-10-29)" class="md-nav__link">
Version 2.3.1 (2018-10-29)
</a>
</li>
<li class="md-nav__item">
<a href="#version-230-2018-08-30" title="Version 2.3.0 (2018-08-30)" class="md-nav__link">
Version 2.3.0 (2018-08-30)
</a>
</li>
...@@ -695,23 +737,91 @@ ...@@ -695,23 +737,91 @@
<h1 id="release-notes">Release Notes<a class="headerlink" href="#release-notes" title="Permanent link">&para;</a></h1> <h1 id="release-notes">Release Notes<a class="headerlink" href="#release-notes" title="Permanent link">&para;</a></h1>
<hr />
<h2 id="version-242-2019-01-08">Version 2.4.2 (2019-01-08)<a class="headerlink" href="#version-242-2019-01-08" title="Permanent link">&para;</a></h2> <h2 id="version-242-2019-01-08">Version 2.4.2 (2019-01-08)<a class="headerlink" href="#version-242-2019-01-08" title="Permanent link">&para;</a></h2>
<p><strong>Features:</strong></p> <p><strong>Features:</strong></p>
<ul> <ul>
<li>Startup the CAP with the .NET Core 2.1 BackgroundService. <a class="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. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/265" title="GitHub Issue: dotnetcore/cap#265">#265</a>)</li>
<li>Improved message delivery performance. <a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/261" title="GitHub Issue: dotnetcore/cap#261">#261</a></li> <li>Improved message delivery performance. <a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/261" title="GitHub Issue: dotnetcore/cap#261">#261</a></li>
</ul> </ul>
<p><strong>Bug Fixed:</strong></p> <p><strong>Bug Fixed:</strong></p>
<ul> <ul>
<li>Fixed PostgreSql version isolation feature bug. <a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/256" title="GitHub Issue: dotnetcore/cap#256">#256</a></li> <li>Fixed PostgreSql version isolation feature bug. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/256" title="GitHub Issue: dotnetcore/cap#256">#256</a>)</li>
<li>Fixed SQL Server sql bug for dashboard search. <a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/266" title="GitHub Issue: dotnetcore/cap#266">#266</a></li> <li>Fixed SQL Server sql bug for dashboard search. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/266" title="GitHub Issue: dotnetcore/cap#266">#266</a>)</li>
</ul> </ul>
<h2 id="version-241-2018-12-19">Version 2.4.1 (2018-12-19)<a class="headerlink" href="#version-241-2018-12-19" title="Permanent link">&para;</a></h2> <h2 id="version-241-2018-12-19">Version 2.4.1 (2018-12-19)<a class="headerlink" href="#version-241-2018-12-19" title="Permanent link">&para;</a></h2>
<p><strong>Bug Fixed:</strong></p> <p><strong>Bug Fixed:</strong></p>
<ul> <ul>
<li>Fixed MongoDB version isolation feature bug. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/253" title="GitHub Issue: dotnetcore/cap#253">#253</a>)</li> <li>Fixed MongoDB version isolation feature bug. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/253" title="GitHub Issue: dotnetcore/cap#253">#253</a>)</li>
</ul> </ul>
<h2 id="version-240-2018-12-08">Version 2.4.0 (2018-12-08)<a class="headerlink" href="#version-240-2018-12-08" title="Permanent link">&para;</a></h2>
<p><strong>Features:</strong></p>
<ul>
<li>Supported version options. (<a class="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>
<p><strong>MySQL</strong>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">ALTER</span> <span class="k">TABLE</span> <span class="o">`</span><span class="n">cap</span><span class="p">.</span><span class="n">published</span><span class="o">`</span> <span class="k">ADD</span> <span class="k">Version</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">20</span><span class="p">)</span> <span class="k">NULL</span><span class="p">;</span>
<span class="k">ALTER</span> <span class="k">TABLE</span> <span class="o">`</span><span class="n">cap</span><span class="p">.</span><span class="n">received</span><span class="o">`</span> <span class="k">ADD</span> <span class="k">Version</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">20</span><span class="p">)</span> <span class="k">NULL</span><span class="p">;</span>
</pre></div>
</td></tr></table></p>
<p><strong>SQL Server</strong>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">ALTER</span> <span class="k">TABLE</span> <span class="n">Cap</span><span class="p">.[</span><span class="n">Published</span><span class="p">]</span> <span class="k">ADD</span> <span class="k">Version</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">20</span><span class="p">)</span> <span class="k">NULL</span><span class="p">;</span>
<span class="k">ALTER</span> <span class="k">TABLE</span> <span class="n">Cap</span><span class="p">.[</span><span class="n">Received</span><span class="p">]</span> <span class="k">ADD</span> <span class="k">Version</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">20</span><span class="p">)</span> <span class="k">NULL</span><span class="p">;</span>
</pre></div>
</td></tr></table></p>
<p><strong>PostgreSQL</strong>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">ALTER</span> <span class="k">TABLE</span> <span class="n">cap</span><span class="p">.</span><span class="n">published</span> <span class="k">ADD</span> <span class="ss">&quot;Version&quot;</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">20</span><span class="p">)</span> <span class="k">NULL</span><span class="p">;</span>
<span class="k">ALTER</span> <span class="k">TABLE</span> <span class="n">cap</span><span class="p">.</span><span class="n">received</span> <span class="k">ADD</span> <span class="ss">&quot;Version&quot;</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">20</span><span class="p">)</span> <span class="k">NULL</span><span class="p">;</span>
</pre></div>
</td></tr></table></p>
<p><strong>MongoDb</strong>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>db.CapPublishedMessage.update({},{&quot;$set&quot; : {&quot;Version&quot; : &quot;1&quot;}});
db.CapReceivedMessage.update({},{&quot;$set&quot; : {&quot;Version&quot; : &quot;1&quot;}});
</pre></div>
</td></tr></table></p>
<p><strong>Bug Fixed:</strong></p>
<ul>
<li>Fixed different groups of the same topic name in one instance will cause routing bug. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/235" title="GitHub Issue: dotnetcore/cap#235">#235</a>)</li>
<li>Fixed message presistence bug. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/240" title="GitHub Issue: dotnetcore/cap#240">#240</a>)</li>
<li>Fixed RabbitMQ topic name contains numbers will cause exception bug. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/181" title="GitHub Issue: dotnetcore/cap#181">#181</a>)</li>
</ul>
<h2 id="version-231-2018-10-29">Version 2.3.1 (2018-10-29)<a class="headerlink" href="#version-231-2018-10-29" title="Permanent link">&para;</a></h2>
<p><strong>Features:</strong></p>
<ul>
<li>Add Source Link Support</li>
<li>Upgrade dependent NuGet packages.</li>
</ul>
<p><strong>Bug Fixed:</strong></p>
<ul>
<li>Fixed dashboard messages requeue error. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/205" title="GitHub Issue: dotnetcore/cap#205">#205</a>)</li>
<li>Adjustment snowflake workerId to random id.</li>
<li>Fixed flush unclaer data bug.</li>
</ul>
<h2 id="version-230-2018-08-30">Version 2.3.0 (2018-08-30)<a class="headerlink" href="#version-230-2018-08-30" title="Permanent link">&para;</a></h2>
<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 <a class="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. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/180" title="GitHub Issue: dotnetcore/cap#180">#180</a>)</li>
<li>New publisher Api. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/188" title="GitHub Issue: dotnetcore/cap#188">#188</a>)</li>
</ul>
<p><strong>Features:</strong></p>
<ul>
<li>MongoDb supported. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/143" title="GitHub Issue: dotnetcore/cap#143">#143</a>)</li>
<li>Automatic commit transaction. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/191" title="GitHub Issue: dotnetcore/cap#191">#191</a>)</li>
</ul>
<p><strong>Bug Fixed:</strong></p>
<ul>
<li>Fix message still sent if transaction faild bug. (<a class="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. (<a class="magiclink magiclink-github magiclink-issue" href="https://github.com/dotnetcore/cap/issues/171" title="GitHub Issue: dotnetcore/cap#171">#171</a>)</li>
</ul>
......
...@@ -429,7 +429,7 @@ ...@@ -429,7 +429,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="user-guide/design-principle/" title="Design Principle" class="md-nav__link"> <a href="user-guide/design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -441,7 +441,7 @@ ...@@ -441,7 +441,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="user-guide/implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="user-guide/implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -453,7 +453,7 @@ ...@@ -453,7 +453,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="user-guide/distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="user-guide/transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -21,17 +21,17 @@ ...@@ -21,17 +21,17 @@
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url> </url>
<url> <url>
<loc>https://cap.dotnet-chain.org/user-guide/design-principle/</loc> <loc>https://cap.dotnet-chain.org/user-guide/design/</loc>
<lastmod>2019-02-12</lastmod> <lastmod>2019-02-12</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url> </url>
<url> <url>
<loc>https://cap.dotnet-chain.org/user-guide/implementation-mechanisms/</loc> <loc>https://cap.dotnet-chain.org/user-guide/implementation/</loc>
<lastmod>2019-02-12</lastmod> <lastmod>2019-02-12</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url> </url>
<url> <url>
<loc>https://cap.dotnet-chain.org/user-guide/distributed-transactions/</loc> <loc>https://cap.dotnet-chain.org/user-guide/transaction/</loc>
<lastmod>2019-02-12</lastmod> <lastmod>2019-02-12</lastmod>
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
</url> </url>
......
No preview for this file type
...@@ -379,7 +379,7 @@ ...@@ -379,7 +379,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/design-principle/" title="Design Principle" class="md-nav__link"> <a href="../../user-guide/design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -391,7 +391,7 @@ ...@@ -391,7 +391,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../../user-guide/implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -403,7 +403,7 @@ ...@@ -403,7 +403,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../../user-guide/transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -759,7 +759,53 @@ ...@@ -759,7 +759,53 @@
<p>CAP 的 API 接口只有一个,就是 <code class="codehilite">ICapPublisher</code> 接口,你可以从 DI 容器中获取到该接口的实例进行调用。</p> <p>CAP 的 API 接口只有一个,就是 <code class="codehilite">ICapPublisher</code> 接口,你可以从 DI 容器中获取到该接口的实例进行调用。</p>
<h3 id="_1">发布/发送<a class="headerlink" href="#_1" title="Permanent link">&para;</a></h3> <h3 id="_1">发布/发送<a class="headerlink" href="#_1" title="Permanent link">&para;</a></h3>
<p>你可以使用 <code class="codehilite">ICapPublisher</code> 接口中的 <code class="codehilite">Publish&lt;T&gt;</code> 或者 <code class="codehilite">PublishAsync&lt;T&gt;</code> 方法来发送消息:</p> <p>你可以使用 <code class="codehilite">ICapPublisher</code> 接口中的 <code class="codehilite">Publish&lt;T&gt;</code> 或者 <code class="codehilite">PublishAsync&lt;T&gt;</code> 方法来发送消息:</p>
<div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">class</span> <span class="nc">PublishController</span> <span class="p">:</span> <span class="n">Controller</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">class</span> <span class="nc">PublishController</span> <span class="p">:</span> <span class="n">Controller</span>
<span class="p">{</span> <span class="p">{</span>
<span class="k">private</span> <span class="k">readonly</span> <span class="n">ICapPublisher</span> <span class="n">_capBus</span><span class="p">;</span> <span class="k">private</span> <span class="k">readonly</span> <span class="n">ICapPublisher</span> <span class="n">_capBus</span><span class="p">;</span>
...@@ -807,6 +853,7 @@ ...@@ -807,6 +853,7 @@
<span class="p">}</span> <span class="p">}</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<p>下面是PublishAsync这个接口的签名:</p> <p>下面是PublishAsync这个接口的签名:</p>
<p><strong><code class="codehilite">PublishAsync&lt;T&gt;(string name,T object)</code></strong></p> <p><strong><code class="codehilite">PublishAsync&lt;T&gt;(string name,T object)</code></strong></p>
...@@ -819,7 +866,25 @@ ...@@ -819,7 +866,25 @@
<p>在一些需要业务补偿的场景中,我们可以利用此特性进行一些还原的补偿操作。例如:电商系统中的付款操作,订单在进行支付调用支付服务的过程中如果发生异常,那么支付服务可以通过返回一个结果来告诉调用方此次业务失败,调用方将支付状态标记为失败。 调用方通过订阅 <code class="codehilite">callbackName</code>(订阅参数为消费方方法的返回值) 即可接收到支付服务消费者方法的返回结果,从而进行补偿的业务处理。</p> <p>在一些需要业务补偿的场景中,我们可以利用此特性进行一些还原的补偿操作。例如:电商系统中的付款操作,订单在进行支付调用支付服务的过程中如果发生异常,那么支付服务可以通过返回一个结果来告诉调用方此次业务失败,调用方将支付状态标记为失败。 调用方通过订阅 <code class="codehilite">callbackName</code>(订阅参数为消费方方法的返回值) 即可接收到支付服务消费者方法的返回结果,从而进行补偿的业务处理。</p>
</blockquote> </blockquote>
<p>下面是使用方法:</p> <p>下面是使用方法:</p>
<div class="codehilite"><pre><span></span><span class="c1">// 发送方</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="c1">// 发送方</span>
<span class="n">_capBus</span><span class="p">.</span><span class="n">Publish</span><span class="p">(</span><span class="s">&quot;xxx.services.show.time&quot;</span><span class="p">,</span><span class="n">DaateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">,</span><span class="s">&quot;callback-show-execute-time&quot;</span><span class="p">);</span> <span class="n">_capBus</span><span class="p">.</span><span class="n">Publish</span><span class="p">(</span><span class="s">&quot;xxx.services.show.time&quot;</span><span class="p">,</span><span class="n">DaateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">,</span><span class="s">&quot;callback-show-execute-time&quot;</span><span class="p">);</span>
<span class="na">[CapSubscribe(&quot;callback-show-execute-time&quot;)]</span> <span class="c1">//对应发送的 callbackName</span> <span class="na">[CapSubscribe(&quot;callback-show-execute-time&quot;)]</span> <span class="c1">//对应发送的 callbackName</span>
...@@ -839,6 +904,7 @@ ...@@ -839,6 +904,7 @@
<span class="k">return</span> <span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">;</span> <span class="c1">// 这是消费者返回的时间,CAP会取该方法的返回值用来传递到发送方的回调订阅里面</span> <span class="k">return</span> <span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">;</span> <span class="c1">// 这是消费者返回的时间,CAP会取该方法的返回值用来传递到发送方的回调订阅里面</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<h4 id="_3">事务<a class="headerlink" href="#_3" title="Permanent link">&para;</a></h4> <h4 id="_3">事务<a class="headerlink" href="#_3" title="Permanent link">&para;</a></h4>
<p>事务在 CAP 具有重要作用,它是保证消息可靠性的一个基石。 在发送一条消息到消息队列的过程中,如果不使用事务,我们是没有办法保证我们的业务代码在执行成功后消息已经成功的发送到了消息队列,或者是消息成功的发送到了消息队列,但是业务代码确执行失败。</p> <p>事务在 CAP 具有重要作用,它是保证消息可靠性的一个基石。 在发送一条消息到消息队列的过程中,如果不使用事务,我们是没有办法保证我们的业务代码在执行成功后消息已经成功的发送到了消息队列,或者是消息成功的发送到了消息队列,但是业务代码确执行失败。</p>
...@@ -848,7 +914,14 @@ ...@@ -848,7 +914,14 @@
<ul> <ul>
<li>EntityFramework</li> <li>EntityFramework</li>
</ul> </ul>
<div class="codehilite"><pre><span></span><span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">trans</span> <span class="p">=</span> <span class="n">dbContext</span><span class="p">.</span><span class="n">Database</span><span class="p">.</span><span class="n">BeginTransaction</span><span class="p">(</span><span class="n">_capBus</span><span class="p">,</span> <span class="n">autoCommit</span><span class="p">:</span> <span class="k">false</span><span class="p">)</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">trans</span> <span class="p">=</span> <span class="n">dbContext</span><span class="p">.</span><span class="n">Database</span><span class="p">.</span><span class="n">BeginTransaction</span><span class="p">(</span><span class="n">_capBus</span><span class="p">,</span> <span class="n">autoCommit</span><span class="p">:</span> <span class="k">false</span><span class="p">)</span>
<span class="p">{</span> <span class="p">{</span>
<span class="c1">//业务代码</span> <span class="c1">//业务代码</span>
...@@ -857,6 +930,7 @@ ...@@ -857,6 +930,7 @@
<span class="n">trans</span><span class="p">.</span><span class="n">Commit</span><span class="p">();</span> <span class="n">trans</span><span class="p">.</span><span class="n">Commit</span><span class="p">();</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<p>在不使用自动提交的时候,你的业务代码可以位于 Publish 之前或者之后,只需要保证在同一个事务。 </p> <p>在不使用自动提交的时候,你的业务代码可以位于 Publish 之前或者之后,只需要保证在同一个事务。 </p>
<p>当使用自动提交时候,需要确保 <code class="codehilite">_capBus.Publish</code> 位于代码的最后。</p> <p>当使用自动提交时候,需要确保 <code class="codehilite">_capBus.Publish</code> 位于代码的最后。</p>
...@@ -864,7 +938,18 @@ ...@@ -864,7 +938,18 @@
<ul> <ul>
<li>Dapper</li> <li>Dapper</li>
</ul> </ul>
<div class="codehilite"><pre><span></span><span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">connection</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MySqlConnection</span><span class="p">(</span><span class="n">ConnectionString</span><span class="p">))</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span> 1
2
3
4
5
6
7
8
9
10
11
12</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">connection</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MySqlConnection</span><span class="p">(</span><span class="n">ConnectionString</span><span class="p">))</span>
<span class="p">{</span> <span class="p">{</span>
<span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">transaction</span> <span class="p">=</span> <span class="n">connection</span><span class="p">.</span><span class="n">BeginTransaction</span><span class="p">(</span><span class="n">_capBus</span><span class="p">,</span> <span class="n">autoCommit</span><span class="p">:</span> <span class="k">false</span><span class="p">))</span> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">transaction</span> <span class="p">=</span> <span class="n">connection</span><span class="p">.</span><span class="n">BeginTransaction</span><span class="p">(</span><span class="n">_capBus</span><span class="p">,</span> <span class="n">autoCommit</span><span class="p">:</span> <span class="k">false</span><span class="p">))</span>
<span class="p">{</span> <span class="p">{</span>
...@@ -877,25 +962,37 @@ ...@@ -877,25 +962,37 @@
<span class="p">}</span> <span class="p">}</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<h3 id="_4">订阅/消费<a class="headerlink" href="#_4" title="Permanent link">&para;</a></h3> <h3 id="_4">订阅/消费<a class="headerlink" href="#_4" title="Permanent link">&para;</a></h3>
<p><strong>注意:框架无法做到100%确保消息只执行一次,所以在一些关键场景消息端在方法实现的过程中自己保证幂等性。</strong></p> <p><strong>注意:框架无法做到100%确保消息只执行一次,所以在一些关键场景消息端在方法实现的过程中自己保证幂等性。</strong></p>
<p>使用 <code class="codehilite">CapSubscribeAttribute</code> 来订阅 CAP 发布出去的消息。</p> <p>使用 <code class="codehilite">CapSubscribeAttribute</code> 来订阅 CAP 发布出去的消息。</p>
<div class="codehilite"><pre><span></span><span class="k">[CapSubscribe(&quot;xxx.services.bar&quot;)]</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">[CapSubscribe(&quot;xxx.services.bar&quot;)]</span>
<span class="na">public void BarMessageProcessor()</span> <span class="na">public void BarMessageProcessor()</span>
<span class="na">{</span> <span class="na">{</span>
<span class="na">}</span> <span class="na">}</span>
</pre></div> </pre></div>
</td></tr></table>
<p>这里,你也可以使用多个 <code class="codehilite">CapSubscribe[&quot;&quot;]</code> 来同时订阅多个不同的消息 :</p> <p>这里,你也可以使用多个 <code class="codehilite">CapSubscribe[&quot;&quot;]</code> 来同时订阅多个不同的消息 :</p>
<div class="codehilite"><pre><span></span><span class="k">[CapSubscribe(&quot;xxx.services.bar&quot;)]</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5
6</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">[CapSubscribe(&quot;xxx.services.bar&quot;)]</span>
<span class="k">[CapSubscribe(&quot;xxx.services.foo&quot;)]</span> <span class="k">[CapSubscribe(&quot;xxx.services.foo&quot;)]</span>
<span class="na">public void BarAndFooMessageProcessor()</span> <span class="na">public void BarAndFooMessageProcessor()</span>
<span class="na">{</span> <span class="na">{</span>
<span class="na">}</span> <span class="na">}</span>
</pre></div> </pre></div>
</td></tr></table>
<p>其中,<code class="codehilite">xxx.services.bar</code> 为订阅的消息名称,内部实现上,这个名称在不同的消息队列具有不同的代表。 在 Kafka 中,这个名称即为 Topic Name。 在RabbitMQ 中,为 RouteKey。</p> <p>其中,<code class="codehilite">xxx.services.bar</code> 为订阅的消息名称,内部实现上,这个名称在不同的消息队列具有不同的代表。 在 Kafka 中,这个名称即为 Topic Name。 在RabbitMQ 中,为 RouteKey。</p>
<blockquote> <blockquote>
...@@ -914,12 +1011,17 @@ ...@@ -914,12 +1011,17 @@
<p><strong>组(Group)</strong>,是订阅者的一个集合,每一组可以有一个或者多个消费者,但是一个订阅者只能属于某一个组。同一个组内的订阅者订阅的消息只能被消费一次。</p> <p><strong>组(Group)</strong>,是订阅者的一个集合,每一组可以有一个或者多个消费者,但是一个订阅者只能属于某一个组。同一个组内的订阅者订阅的消息只能被消费一次。</p>
<p>如果你在订阅的时候没有指定组,CAP会将订阅者设置到一个默认的组,默认的组名称为 <code class="codehilite">cap.queue.{程序集名称}</code></p> <p>如果你在订阅的时候没有指定组,CAP会将订阅者设置到一个默认的组,默认的组名称为 <code class="codehilite">cap.queue.{程序集名称}</code></p>
<p>以下是使用组进行订阅的示例:</p> <p>以下是使用组进行订阅的示例:</p>
<div class="codehilite"><pre><span></span><span class="na">[CapSubscribe(&quot;xxx.services.foo&quot;, Group = &quot;moduleA&quot;)]</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="na">[CapSubscribe(&quot;xxx.services.foo&quot;, Group = &quot;moduleA&quot;)]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">FooMessageProcessor</span><span class="p">()</span> <span class="k">public</span> <span class="k">void</span> <span class="nf">FooMessageProcessor</span><span class="p">()</span>
<span class="p">{</span> <span class="p">{</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<h4 id="_5">例外情况<a class="headerlink" href="#_5" title="Permanent link">&para;</a></h4> <h4 id="_5">例外情况<a class="headerlink" href="#_5" title="Permanent link">&para;</a></h4>
<p>这里有几种情况可能需要知道:</p> <p>这里有几种情况可能需要知道:</p>
......
...@@ -379,7 +379,7 @@ ...@@ -379,7 +379,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/design-principle/" title="Design Principle" class="md-nav__link"> <a href="../../user-guide/design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -391,7 +391,7 @@ ...@@ -391,7 +391,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../../user-guide/implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -403,7 +403,7 @@ ...@@ -403,7 +403,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../../user-guide/transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -790,10 +790,13 @@ ...@@ -790,10 +790,13 @@
<p>CAP 使用 Microsoft.Extensions.DependencyInjection 进行配置的注入,你也可以依赖于 DI 从json文件中读取配置。</p> <p>CAP 使用 Microsoft.Extensions.DependencyInjection 进行配置的注入,你也可以依赖于 DI 从json文件中读取配置。</p>
<h3 id="cap-options">Cap Options<a class="headerlink" href="#cap-options" title="Permanent link">&para;</a></h3> <h3 id="cap-options">Cap Options<a class="headerlink" href="#cap-options" title="Permanent link">&para;</a></h3>
<p>你可以使用如下方式来配置 CAP 中的一些配置项,例如</p> <p>你可以使用如下方式来配置 CAP 中的一些配置项,例如</p>
<div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; { <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; {
capOptions.FailedCallback = //... capOptions.FailedCallback = //...
}); });
</pre></div> </pre></div>
</td></tr></table>
<p><code class="codehilite">CapOptions</code> 提供了以下配置项:</p> <p><code class="codehilite">CapOptions</code> 提供了以下配置项:</p>
<table> <table>
...@@ -842,12 +845,17 @@ ...@@ -842,12 +845,17 @@
<p>FailedCallback 的类型为 <code class="codehilite">Action&lt;MessageType,string,string&gt;</code>,第一个参数为消息类型(发送的还是接收的),第二个参数为消息的名称(name),第三个参数为消息的内容(content)。</p> <p>FailedCallback 的类型为 <code class="codehilite">Action&lt;MessageType,string,string&gt;</code>,第一个参数为消息类型(发送的还是接收的),第二个参数为消息的名称(name),第三个参数为消息的内容(content)。</p>
<h3 id="rabbitmq-options">RabbitMQ Options<a class="headerlink" href="#rabbitmq-options" title="Permanent link">&para;</a></h3> <h3 id="rabbitmq-options">RabbitMQ Options<a class="headerlink" href="#rabbitmq-options" title="Permanent link">&para;</a></h3>
<p>CAP 采用的是针对 CapOptions 进行扩展来实现RabbitMQ的配置功能,所以针对 RabbitMQ 的配置用法如下:</p> <p>CAP 采用的是针对 CapOptions 进行扩展来实现RabbitMQ的配置功能,所以针对 RabbitMQ 的配置用法如下:</p>
<div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; { <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; {
capOptions.UseRabbitMQ(rabbitMQOption=&gt;{ capOptions.UseRabbitMQ(rabbitMQOption=&gt;{
// rabbitmq options. // rabbitmq options.
}); });
}); });
</pre></div> </pre></div>
</td></tr></table>
<p><code class="codehilite">RabbitMQOptions</code> 提供了有关RabbitMQ相关的配置:</p> <p><code class="codehilite">RabbitMQOptions</code> 提供了有关RabbitMQ相关的配置:</p>
<table> <table>
...@@ -924,19 +932,31 @@ ...@@ -924,19 +932,31 @@
</table> </table>
<h3 id="kafka-options">Kafka Options<a class="headerlink" href="#kafka-options" title="Permanent link">&para;</a></h3> <h3 id="kafka-options">Kafka Options<a class="headerlink" href="#kafka-options" title="Permanent link">&para;</a></h3>
<p>CAP 采用的是针对 CapOptions 进行扩展来实现 Kafka 的配置功能,所以针对 Kafka 的配置用法如下:</p> <p>CAP 采用的是针对 CapOptions 进行扩展来实现 Kafka 的配置功能,所以针对 Kafka 的配置用法如下:</p>
<div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; { <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5
6</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; {
capOptions.UseKafka(kafkaOption=&gt;{ capOptions.UseKafka(kafkaOption=&gt;{
// kafka options. // kafka options.
// kafkaOptions.MainConfig.Add(&quot;&quot;, &quot;&quot;); // kafkaOptions.MainConfig.Add(&quot;&quot;, &quot;&quot;);
}); });
}); });
</pre></div> </pre></div>
</td></tr></table>
<p><code class="codehilite">KafkaOptions</code> 提供了有关 Kafka 相关的配置,由于Kafka的配置比较多,所以此处使用的是提供的 MainConfig 字典来支持进行自定义配置,你可以查看这里来获取对配置项的支持信息。</p> <p><code class="codehilite">KafkaOptions</code> 提供了有关 Kafka 相关的配置,由于Kafka的配置比较多,所以此处使用的是提供的 MainConfig 字典来支持进行自定义配置,你可以查看这里来获取对配置项的支持信息。</p>
<p><a href="https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md">https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md</a></p> <p><a href="https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md">https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md</a></p>
<h3 id="entityframework-options">EntityFramework Options<a class="headerlink" href="#entityframework-options" title="Permanent link">&para;</a></h3> <h3 id="entityframework-options">EntityFramework Options<a class="headerlink" href="#entityframework-options" title="Permanent link">&para;</a></h3>
<p>如果使用的 Entityframework 来作为消息持久化存储的话,那么你可以在配置 CAP EntityFramework 配置项的时候来自定义一些配置。</p> <p>如果使用的 Entityframework 来作为消息持久化存储的话,那么你可以在配置 CAP EntityFramework 配置项的时候来自定义一些配置。</p>
<div class="codehilite"><pre><span></span>services.AddCap(x =&gt; <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(x =&gt;
{ {
x.UseEntityFramework&lt;AppDbContext&gt;(efOption =&gt; x.UseEntityFramework&lt;AppDbContext&gt;(efOption =&gt;
{ {
...@@ -944,6 +964,7 @@ ...@@ -944,6 +964,7 @@
}); });
}); });
</pre></div> </pre></div>
</td></tr></table>
<p>注意,如果你使用了 <code class="codehilite">UseEntityFramework</code> 的配置项,那么你不需要再次配置下面的章节几个针对不同数据库的配置,CAP 将会自动读取 DbContext 中使用的数据库相关配置信息。</p> <p>注意,如果你使用了 <code class="codehilite">UseEntityFramework</code> 的配置项,那么你不需要再次配置下面的章节几个针对不同数据库的配置,CAP 将会自动读取 DbContext 中使用的数据库相关配置信息。</p>
<table> <table>
...@@ -979,12 +1000,17 @@ ...@@ -979,12 +1000,17 @@
<h3 id="sqlserver-options">SqlServer Options<a class="headerlink" href="#sqlserver-options" title="Permanent link">&para;</a></h3> <h3 id="sqlserver-options">SqlServer Options<a class="headerlink" href="#sqlserver-options" title="Permanent link">&para;</a></h3>
<p>注意,如果你使用的是 EntityFramewrok,你用不到此配置项。</p> <p>注意,如果你使用的是 EntityFramewrok,你用不到此配置项。</p>
<p>CAP 采用的是针对 CapOptions 进行扩展来实现 SqlServer 的配置功能,所以针对 SqlServer 的配置用法如下:</p> <p>CAP 采用的是针对 CapOptions 进行扩展来实现 SqlServer 的配置功能,所以针对 SqlServer 的配置用法如下:</p>
<div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; { <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; {
capOptions.UseSqlServer(sqlserverOptions =&gt; { capOptions.UseSqlServer(sqlserverOptions =&gt; {
// sqlserverOptions.ConnectionString // sqlserverOptions.ConnectionString
}); });
}); });
</pre></div> </pre></div>
</td></tr></table>
<table> <table>
<thead> <thead>
...@@ -1013,12 +1039,17 @@ ...@@ -1013,12 +1039,17 @@
<h3 id="mysql-options">MySql Options<a class="headerlink" href="#mysql-options" title="Permanent link">&para;</a></h3> <h3 id="mysql-options">MySql Options<a class="headerlink" href="#mysql-options" title="Permanent link">&para;</a></h3>
<p>注意,如果你使用的是 EntityFramewrok,你用不到此配置项。</p> <p>注意,如果你使用的是 EntityFramewrok,你用不到此配置项。</p>
<p>CAP 采用的是针对 CapOptions 进行扩展来实现 MySql 的配置功能,所以针对 MySql 的配置用法如下:</p> <p>CAP 采用的是针对 CapOptions 进行扩展来实现 MySql 的配置功能,所以针对 MySql 的配置用法如下:</p>
<div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; { <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; {
capOptions.UseMySql(mysqlOptions =&gt; { capOptions.UseMySql(mysqlOptions =&gt; {
// mysqlOptions.ConnectionString // mysqlOptions.ConnectionString
}); });
}); });
</pre></div> </pre></div>
</td></tr></table>
<table> <table>
<thead> <thead>
...@@ -1047,12 +1078,17 @@ ...@@ -1047,12 +1078,17 @@
<h3 id="postgresql-options">PostgreSql Options<a class="headerlink" href="#postgresql-options" title="Permanent link">&para;</a></h3> <h3 id="postgresql-options">PostgreSql Options<a class="headerlink" href="#postgresql-options" title="Permanent link">&para;</a></h3>
<p>注意,如果你使用的是 EntityFramewrok,你用不到此配置项。</p> <p>注意,如果你使用的是 EntityFramewrok,你用不到此配置项。</p>
<p>CAP 采用的是针对 CapOptions 进行扩展来实现 PostgreSql 的配置功能,所以针对 PostgreSql 的配置用法如下:</p> <p>CAP 采用的是针对 CapOptions 进行扩展来实现 PostgreSql 的配置功能,所以针对 PostgreSql 的配置用法如下:</p>
<div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; { <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; {
capOptions.UsePostgreSql(postgreOptions =&gt; { capOptions.UsePostgreSql(postgreOptions =&gt; {
// postgreOptions.ConnectionString // postgreOptions.ConnectionString
}); });
}); });
</pre></div> </pre></div>
</td></tr></table>
<table> <table>
<thead> <thead>
......
...@@ -379,7 +379,7 @@ ...@@ -379,7 +379,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/design-principle/" title="Design Principle" class="md-nav__link"> <a href="../../user-guide/design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -391,7 +391,7 @@ ...@@ -391,7 +391,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../../user-guide/implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -403,7 +403,7 @@ ...@@ -403,7 +403,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../../user-guide/transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
......
...@@ -379,7 +379,7 @@ ...@@ -379,7 +379,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/design-principle/" title="Design Principle" class="md-nav__link"> <a href="../../user-guide/design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -391,7 +391,7 @@ ...@@ -391,7 +391,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../../user-guide/implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -403,7 +403,7 @@ ...@@ -403,7 +403,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../../user-guide/transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
......
...@@ -375,7 +375,7 @@ ...@@ -375,7 +375,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/design-principle/" title="Design Principle" class="md-nav__link"> <a href="../../user-guide/design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -387,7 +387,7 @@ ...@@ -387,7 +387,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../../user-guide/implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -399,7 +399,7 @@ ...@@ -399,7 +399,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../../user-guide/transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -627,7 +627,18 @@ QQ群有效沟通太低,浪费时间。</p> ...@@ -627,7 +627,18 @@ QQ群有效沟通太低,浪费时间。</p>
<p><strong>3、CAP如何在不同的实例中使用相同的数据库?</strong></p> <p><strong>3、CAP如何在不同的实例中使用相同的数据库?</strong></p>
<p>如果想在不同的实例(程序)中连接相同的数据库,那么你可以在配置CAP的时候通过指定不同的数据库表名前缀来实现。</p> <p>如果想在不同的实例(程序)中连接相同的数据库,那么你可以在配置CAP的时候通过指定不同的数据库表名前缀来实现。</p>
<p>你可以通过以下方式来指定数据库表名前缀:</p> <p>你可以通过以下方式来指定数据库表名前缀:</p>
<p><div class="codehilite"><pre><span></span>public void ConfigureServices(IServiceCollection services) <p><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span> 1
2
3
4
5
6
7
8
9
10
11
12</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>public void ConfigureServices(IServiceCollection services)
{ {
services.AddCap(x =&gt; services.AddCap(x =&gt;
{ {
...@@ -640,6 +651,7 @@ QQ群有效沟通太低,浪费时间。</p> ...@@ -640,6 +651,7 @@ QQ群有效沟通太低,浪费时间。</p>
}); });
} }
</pre></div> </pre></div>
</td></tr></table>
注意:相同的实例不需要指定不同的表名称前缀,他们在接收消息的时候会进行负载均衡。</p> 注意:相同的实例不需要指定不同的表名称前缀,他们在接收消息的时候会进行负载均衡。</p>
<p><strong>4、CAP可以不使用数据库吗? 我仅仅是想通过她来传递消息,我可以接受消息丢失的情况</strong> </p> <p><strong>4、CAP可以不使用数据库吗? 我仅仅是想通过她来传递消息,我可以接受消息丢失的情况</strong> </p>
<p>目前是不可以的。 </p> <p>目前是不可以的。 </p>
......
...@@ -379,7 +379,7 @@ ...@@ -379,7 +379,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/design-principle/" title="Design Principle" class="md-nav__link"> <a href="../../user-guide/design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -391,7 +391,7 @@ ...@@ -391,7 +391,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../../user-guide/implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -403,7 +403,7 @@ ...@@ -403,7 +403,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../../user-guide/transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -732,26 +732,59 @@ ...@@ -732,26 +732,59 @@
<li><strong>引用 NuGet 包</strong></li> <li><strong>引用 NuGet 包</strong></li>
</ul> </ul>
<p>使用一下命令来引用CAP的NuGet包:</p> <p>使用一下命令来引用CAP的NuGet包:</p>
<div class="codehilite"><pre><span></span>PM&gt; Install-Package DotNetCore.CAP <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>PM&gt; Install-Package DotNetCore.CAP
</pre></div> </pre></div>
</td></tr></table>
<p>根据使用的不同类型的消息队列,来引入不同的扩展包:</p> <p>根据使用的不同类型的消息队列,来引入不同的扩展包:</p>
<div class="codehilite"><pre><span></span>PM&gt; Install-Package DotNetCore.CAP.RabbitMQ <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>PM&gt; Install-Package DotNetCore.CAP.RabbitMQ
PM&gt; Install-Package DotNetCore.CAP.Kafka PM&gt; Install-Package DotNetCore.CAP.Kafka
</pre></div> </pre></div>
</td></tr></table>
<p>根据使用的不同类型的数据库,来引入不同的扩展包:</p> <p>根据使用的不同类型的数据库,来引入不同的扩展包:</p>
<div class="codehilite"><pre><span></span>PM&gt; Install-Package DotNetCore.CAP.SqlServer <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>PM&gt; Install-Package DotNetCore.CAP.SqlServer
PM&gt; Install-Package DotNetCore.CAP.MySql PM&gt; Install-Package DotNetCore.CAP.MySql
PM&gt; Install-Package DotNetCore.CAP.PostgreSql PM&gt; Install-Package DotNetCore.CAP.PostgreSql
PM&gt; Install-Package DotNetCore.CAP.MongoDB PM&gt; Install-Package DotNetCore.CAP.MongoDB
</pre></div> </pre></div>
</td></tr></table>
<ul> <ul>
<li><strong>启动配置</strong></li> <li><strong>启动配置</strong></li>
</ul> </ul>
<p>在 ASP.NET Core 程序中,你可以在 <code class="codehilite">Startup.cs</code> 文件 <code class="codehilite">ConfigureServices()</code> 中配置 CAP 使用到的服务:</p> <p>在 ASP.NET Core 程序中,你可以在 <code class="codehilite">Startup.cs</code> 文件 <code class="codehilite">ConfigureServices()</code> 中配置 CAP 使用到的服务:</p>
<div class="codehilite"><pre><span></span>public void ConfigureServices(IServiceCollection services) <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>public void ConfigureServices(IServiceCollection services)
{ {
//...... //......
...@@ -779,6 +812,7 @@ PM&gt; Install-Package DotNetCore.CAP.MongoDB ...@@ -779,6 +812,7 @@ PM&gt; Install-Package DotNetCore.CAP.MongoDB
}); });
} }
</pre></div> </pre></div>
</td></tr></table>
......
...@@ -379,7 +379,7 @@ ...@@ -379,7 +379,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/design-principle/" title="Design Principle" class="md-nav__link"> <a href="../../user-guide/design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -391,7 +391,7 @@ ...@@ -391,7 +391,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../../user-guide/implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -403,7 +403,7 @@ ...@@ -403,7 +403,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../../user-guide/distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../../user-guide/transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
......
...@@ -492,7 +492,7 @@ ...@@ -492,7 +492,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../design-principle/" title="Design Principle" class="md-nav__link"> <a href="../design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -504,7 +504,7 @@ ...@@ -504,7 +504,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -516,7 +516,7 @@ ...@@ -516,7 +516,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -830,7 +830,44 @@ ...@@ -830,7 +830,44 @@
<p>CAP only has one interface,It is <code class="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 <code class="codehilite">ICapPublisher</code>, You can get its instance from the DI container and then call it.</p>
<h2 id="publish-send">Publish &amp; Send<a class="headerlink" href="#publish-send" title="Permanent link">&para;</a></h2> <h2 id="publish-send">Publish &amp; Send<a class="headerlink" href="#publish-send" title="Permanent link">&para;</a></h2>
<p>You can use the <code class="codehilite">Publish&lt;T&gt;</code> or <code class="codehilite">PublishAsync&lt;T&gt;</code> methods defined in the <code class="codehilite">ICapPublisher</code> interface to send the event messages.</p> <p>You can use the <code class="codehilite">Publish&lt;T&gt;</code> or <code class="codehilite">PublishAsync&lt;T&gt;</code> methods defined in the <code class="codehilite">ICapPublisher</code> interface to send the event messages.</p>
<p><div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">class</span> <span class="nc">PublishController</span> <span class="p">:</span> <span class="n">Controller</span> <p><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">class</span> <span class="nc">PublishController</span> <span class="p">:</span> <span class="n">Controller</span>
<span class="p">{</span> <span class="p">{</span>
<span class="k">private</span> <span class="k">readonly</span> <span class="n">ICapPublisher</span> <span class="n">_capBus</span><span class="p">;</span> <span class="k">private</span> <span class="k">readonly</span> <span class="n">ICapPublisher</span> <span class="n">_capBus</span><span class="p">;</span>
...@@ -848,8 +885,8 @@ ...@@ -848,8 +885,8 @@
<span class="p">{</span> <span class="p">{</span>
<span class="c1">//your business code</span> <span class="c1">//your business code</span>
<span class="n">_capBus</span><span class="p">.</span><span class="n">Publish</span><span class="p">(</span><span class="s">&quot;xxx.services.show.time&quot;</span><span class="p">,</span> <span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">);</span> <span class="hll"> <span class="n">_capBus</span><span class="p">.</span><span class="n">Publish</span><span class="p">(</span><span class="s">&quot;xxx.services.show.time&quot;</span><span class="p">,</span> <span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">);</span>
<span class="p">}</span> </span> <span class="p">}</span>
<span class="p">}</span> <span class="p">}</span>
<span class="k">return</span> <span class="nf">Ok</span><span class="p">();</span> <span class="k">return</span> <span class="nf">Ok</span><span class="p">();</span>
...@@ -862,23 +899,26 @@ ...@@ -862,23 +899,26 @@
<span class="p">{</span> <span class="p">{</span>
<span class="c1">//your business code</span> <span class="c1">//your business code</span>
<span class="n">_capBus</span><span class="p">.</span><span class="n">Publish</span><span class="p">(</span><span class="s">&quot;xxx.services.show.time&quot;</span><span class="p">,</span> <span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">);</span> <span class="hll"> <span class="n">_capBus</span><span class="p">.</span><span class="n">Publish</span><span class="p">(</span><span class="s">&quot;xxx.services.show.time&quot;</span><span class="p">,</span> <span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">);</span>
<span class="p">}</span> </span> <span class="p">}</span>
<span class="k">return</span> <span class="nf">Ok</span><span class="p">();</span> <span class="k">return</span> <span class="nf">Ok</span><span class="p">();</span>
<span class="p">}</span> <span class="p">}</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
The following is the signature of the of the PublishAsync method</p> The following is the signature of the of the PublishAsync method</p>
<div class="codehilite"><pre><span></span><span class="n">PublishAsync</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="kt">string</span> <span class="n">name</span><span class="p">,</span> <span class="n">T</span> <span class="kt">object</span><span class="p">)</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="n">PublishAsync</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="kt">string</span> <span class="n">name</span><span class="p">,</span> <span class="n">T</span> <span class="kt">object</span><span class="p">)</span>
</pre></div> </pre></div>
</td></tr></table>
<p>By default,when this method(PublishAsync<T>) is called,CAP will create a transaction internally, <p>By default,when this method(PublishAsync<T>) is called,CAP will create a transaction internally,
and then write messages into the <code class="codehilite">Cap.Published</code> message table.</p> and then write messages into the <code class="codehilite">Cap.Published</code> message table.</p>
<p>In some situations,you may need a callback when a message is sent out, you can use the follwing <p>In some situations,you may need a callback when a message is sent out, you can use the follwing
overload of the <code class="codehilite">PublishAsync&lt;T&gt;</code> method:</p> overload of the <code class="codehilite">PublishAsync&lt;T&gt;</code> method:</p>
<div class="codehilite"><pre><span></span><span class="n">PublishAsync</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="kt">string</span> <span class="n">name</span><span class="p">,</span> <span class="n">T</span> <span class="kt">object</span><span class="p">,</span> <span class="kt">string</span> <span class="n">callBackName</span><span class="p">)</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="n">PublishAsync</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="kt">string</span> <span class="n">name</span><span class="p">,</span> <span class="n">T</span> <span class="kt">object</span><span class="p">,</span> <span class="kt">string</span> <span class="n">callBackName</span><span class="p">)</span>
</pre></div> </pre></div>
</td></tr></table>
<p>In this overload method, <code class="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, <code class="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>
<h3 id="transactions">Transactions<a class="headerlink" href="#transactions" title="Permanent link">&para;</a></h3> <h3 id="transactions">Transactions<a class="headerlink" href="#transactions" title="Permanent link">&para;</a></h3>
...@@ -891,7 +931,14 @@ overload of the <code class="codehilite">PublishAsync&lt;T&gt;</code> method:</p ...@@ -891,7 +931,14 @@ overload of the <code class="codehilite">PublishAsync&lt;T&gt;</code> method:</p
</div> </div>
<p>The following two blocks of code snippet demonstrate how to use transactions in EntityFramework and dapper when publishing messages.</p> <p>The following two blocks of code snippet demonstrate how to use transactions in EntityFramework and dapper when publishing messages.</p>
<h4 id="entityframework">EntityFramework<a class="headerlink" href="#entityframework" title="Permanent link">&para;</a></h4> <h4 id="entityframework">EntityFramework<a class="headerlink" href="#entityframework" title="Permanent link">&para;</a></h4>
<p><div class="codehilite"><pre><span></span> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">trans</span> <span class="p">=</span> <span class="n">dbContext</span><span class="p">.</span><span class="n">Database</span><span class="p">.</span><span class="n">BeginTransaction</span><span class="p">(</span><span class="n">_capBus</span><span class="p">,</span> <span class="n">autoCommit</span><span class="p">:</span> <span class="k">false</span><span class="p">)</span> <p><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">trans</span> <span class="p">=</span> <span class="n">dbContext</span><span class="p">.</span><span class="n">Database</span><span class="p">.</span><span class="n">BeginTransaction</span><span class="p">(</span><span class="n">_capBus</span><span class="p">,</span> <span class="n">autoCommit</span><span class="p">:</span> <span class="k">false</span><span class="p">)</span>
<span class="p">{</span> <span class="p">{</span>
<span class="c1">// Your business logic。</span> <span class="c1">// Your business logic。</span>
...@@ -900,11 +947,23 @@ overload of the <code class="codehilite">PublishAsync&lt;T&gt;</code> method:</p ...@@ -900,11 +947,23 @@ overload of the <code class="codehilite">PublishAsync&lt;T&gt;</code> method:</p
<span class="n">trans</span><span class="p">.</span><span class="n">Commit</span><span class="p">();</span> <span class="n">trans</span><span class="p">.</span><span class="n">Commit</span><span class="p">();</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
When you set the <code class="codehilite"><span class="n">autoCommit</span><span class="o">:</span> <span class="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 <code class="codehilite"><span class="n">autoCommit</span><span class="o">:</span> <span class="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 <code class="codehilite"><span class="n">autoCommit</span><span class="o">:</span> <span class="kc">true</span></code>, you need publish message <code class="codehilite">_capBus.Publish</code> at the last.</p> <p>If you set the <code class="codehilite"><span class="n">autoCommit</span><span class="o">:</span> <span class="kc">true</span></code>, you need publish message <code class="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>
<h4 id="dapper">Dapper<a class="headerlink" href="#dapper" title="Permanent link">&para;</a></h4> <h4 id="dapper">Dapper<a class="headerlink" href="#dapper" title="Permanent link">&para;</a></h4>
<div class="codehilite"><pre><span></span><span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">connection</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MySqlConnection</span><span class="p">(</span><span class="n">ConnectionString</span><span class="p">))</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span> 1
2
3
4
5
6
7
8
9
10
11
12</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">connection</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MySqlConnection</span><span class="p">(</span><span class="n">ConnectionString</span><span class="p">))</span>
<span class="p">{</span> <span class="p">{</span>
<span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">transaction</span> <span class="p">=</span> <span class="n">connection</span><span class="p">.</span><span class="n">BeginTransaction</span><span class="p">(</span><span class="n">_capBus</span><span class="p">,</span> <span class="n">autoCommit</span><span class="p">:</span> <span class="k">false</span><span class="p">))</span> <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">transaction</span> <span class="p">=</span> <span class="n">connection</span><span class="p">.</span><span class="n">BeginTransaction</span><span class="p">(</span><span class="n">_capBus</span><span class="p">,</span> <span class="n">autoCommit</span><span class="p">:</span> <span class="k">false</span><span class="p">))</span>
<span class="p">{</span> <span class="p">{</span>
...@@ -917,6 +976,7 @@ When you set the <code class="codehilite"><span class="n">autoCommit</span><span ...@@ -917,6 +976,7 @@ When you set the <code class="codehilite"><span class="n">autoCommit</span><span
<span class="p">}</span> <span class="p">}</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<h2 id="subscribe-consume">Subscribe &amp; Consume<a class="headerlink" href="#subscribe-consume" title="Permanent link">&para;</a></h2> <h2 id="subscribe-consume">Subscribe &amp; Consume<a class="headerlink" href="#subscribe-consume" title="Permanent link">&para;</a></h2>
<div class="admonition warning"> <div class="admonition warning">
...@@ -925,18 +985,27 @@ When you set the <code class="codehilite"><span class="n">autoCommit</span><span ...@@ -925,18 +985,27 @@ When you set the <code class="codehilite"><span class="n">autoCommit</span><span
<p>You can view more details in this <a href="https://github.com/dotnetcore/CAP/issues/29#issuecomment-451841287">ISSUE</a>.</p> <p>You can view more details in this <a href="https://github.com/dotnetcore/CAP/issues/29#issuecomment-451841287">ISSUE</a>.</p>
</div> </div>
<p>Use <code class="codehilite">CapSubscribe[&quot;&quot;]</code> to decorate a method so that it can subscribe messages published by CAP.</p> <p>Use <code class="codehilite">CapSubscribe[&quot;&quot;]</code> to decorate a method so that it can subscribe messages published by CAP.</p>
<p><div class="codehilite"><pre><span></span><span class="na">[CapSubscribe(&quot;xxx.services.bar&quot;)]</span> <p><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="na">[CapSubscribe(&quot;xxx.services.bar&quot;)]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">BarMessageProcessor</span><span class="p">()</span> <span class="k">public</span> <span class="k">void</span> <span class="nf">BarMessageProcessor</span><span class="p">()</span>
<span class="p">{</span> <span class="p">{</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
You can also use multiple <code class="codehilite">CapSubscribe[&quot;&quot;]</code> to decorate a method so that you can subscribe messages from different sources accordingly.</p> You can also use multiple <code class="codehilite">CapSubscribe[&quot;&quot;]</code> to decorate a method so that you can subscribe messages from different sources accordingly.</p>
<p><div class="codehilite"><pre><span></span><span class="na">[CapSubscribe(&quot;xxx.services.bar&quot;)]</span> <p><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="na">[CapSubscribe(&quot;xxx.services.bar&quot;)]</span>
<span class="na">[CapSubscribe(&quot;xxx.services.foo&quot;)]</span> <span class="na">[CapSubscribe(&quot;xxx.services.foo&quot;)]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">BarAndFooMessageProcessor</span><span class="p">()</span> <span class="k">public</span> <span class="k">void</span> <span class="nf">BarAndFooMessageProcessor</span><span class="p">()</span>
<span class="p">{</span> <span class="p">{</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<code class="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> <code class="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[&quot;&quot;]</c ...@@ -955,12 +1024,17 @@ You can also use multiple <code class="codehilite">CapSubscribe[&quot;&quot;]</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 <code class="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 <code class="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>
<div class="codehilite"><pre><span></span><span class="na">[CapSubscribe(&quot;xxx.services.foo&quot;, Group = &quot;moduleA&quot;)]</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="na">[CapSubscribe(&quot;xxx.services.foo&quot;, Group = &quot;moduleA&quot;)]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">FooMessageProcessor</span><span class="p">()</span> <span class="k">public</span> <span class="k">void</span> <span class="nf">FooMessageProcessor</span><span class="p">()</span>
<span class="p">{</span> <span class="p">{</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<h3 id="exceptional-case">Exceptional case<a class="headerlink" href="#exceptional-case" title="Permanent link">&para;</a></h3> <h3 id="exceptional-case">Exceptional case<a class="headerlink" href="#exceptional-case" title="Permanent link">&para;</a></h3>
<p>The following situations you shoud be aware of.</p> <p>The following situations you shoud be aware of.</p>
......
...@@ -374,6 +374,8 @@ ...@@ -374,6 +374,8 @@
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc"> <input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc"> <label class="md-nav__link md-nav__link--active" for="__toc">
Configuration Configuration
...@@ -387,63 +389,58 @@ ...@@ -387,63 +389,58 @@
<nav class="md-nav md-nav--secondary"> <nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label> <label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#configuration" title="Configuration" class="md-nav__link"> <a href="#cap-configs" title="CAP Configs" class="md-nav__link">
Configuration CAP Configs
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#cap-options" title="Cap Options" class="md-nav__link">
Cap Options
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#rabbitmq-options" title="RabbitMQ Options" class="md-nav__link"> <a href="#rabbitmq-configs" title="RabbitMQ Configs" class="md-nav__link">
RabbitMQ Options RabbitMQ Configs
</a> </a>
</li> <nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#kafka-options" title="Kafka Options" class="md-nav__link"> <a href="#kafka-configs" title="Kafka Configs" class="md-nav__link">
Kafka Options Kafka Configs
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#entityframework-options" title="EntityFramework Options" class="md-nav__link"> <a href="#entityframework-configs" title="EntityFramework Configs" class="md-nav__link">
EntityFramework Options EntityFramework Configs
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#sqlserver-options" title="SqlServer Options" class="md-nav__link"> <a href="#sqlserver-configs" title="SqlServer Configs" class="md-nav__link">
SqlServer Options SqlServer Configs
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#mysql-options" title="MySql Options" class="md-nav__link"> <a href="#mysql-configs" title="MySql Configs" class="md-nav__link">
MySql Options MySql Configs
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#postgresql-options" title="PostgreSql Options" class="md-nav__link"> <a href="#postgresql-configs" title="PostgreSql Configs" class="md-nav__link">
PostgreSql Options PostgreSql Configs
</a> </a>
</li> </li>
...@@ -470,7 +467,7 @@ ...@@ -470,7 +467,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../design-principle/" title="Design Principle" class="md-nav__link"> <a href="../design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -482,7 +479,7 @@ ...@@ -482,7 +479,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -494,7 +491,7 @@ ...@@ -494,7 +491,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -699,63 +696,58 @@ ...@@ -699,63 +696,58 @@
<nav class="md-nav md-nav--secondary"> <nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label> <label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#configuration" title="Configuration" class="md-nav__link"> <a href="#cap-configs" title="CAP Configs" class="md-nav__link">
Configuration CAP Configs
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#cap-options" title="Cap Options" class="md-nav__link">
Cap Options
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#rabbitmq-options" title="RabbitMQ Options" class="md-nav__link"> <a href="#rabbitmq-configs" title="RabbitMQ Configs" class="md-nav__link">
RabbitMQ Options RabbitMQ Configs
</a> </a>
</li> <nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#kafka-options" title="Kafka Options" class="md-nav__link"> <a href="#kafka-configs" title="Kafka Configs" class="md-nav__link">
Kafka Options Kafka Configs
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#entityframework-options" title="EntityFramework Options" class="md-nav__link"> <a href="#entityframework-configs" title="EntityFramework Configs" class="md-nav__link">
EntityFramework Options EntityFramework Configs
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#sqlserver-options" title="SqlServer Options" class="md-nav__link"> <a href="#sqlserver-configs" title="SqlServer Configs" class="md-nav__link">
SqlServer Options SqlServer Configs
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#mysql-options" title="MySql Options" class="md-nav__link"> <a href="#mysql-configs" title="MySql Configs" class="md-nav__link">
MySql Options MySql Configs
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#postgresql-options" title="PostgreSql Options" class="md-nav__link"> <a href="#postgresql-configs" title="PostgreSql Configs" class="md-nav__link">
PostgreSql Options PostgreSql Configs
</a> </a>
</li> </li>
...@@ -784,16 +776,17 @@ ...@@ -784,16 +776,17 @@
<a href="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/configuration.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a> <a href="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/configuration.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a>
<h1>Configuration</h1> <h1 id="configuration">Configuration<a class="headerlink" href="#configuration" title="Permanent link">&para;</a></h1>
<h2 id="configuration">Configuration<a class="headerlink" href="#configuration" title="Permanent link">&para;</a></h2>
<p>CAP uses Microsoft.Extensions.DependencyInjection for configuration injection. </p> <p>CAP uses Microsoft.Extensions.DependencyInjection for configuration injection. </p>
<h3 id="cap-options">Cap Options<a class="headerlink" href="#cap-options" title="Permanent link">&para;</a></h3> <h2 id="cap-configs">CAP Configs<a class="headerlink" href="#cap-configs" title="Permanent link">&para;</a></h2>
<p>You can use the following methods to configure some configuration items in the CAP, for example:</p> <p>You can use the following methods to configure some configuration items in the CAP, for example:</p>
<div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; { <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; {
capOptions.FailedCallback = //... capOptions.FailedCallback = //...
}); });
</pre></div> </pre></div>
</td></tr></table>
<p><code class="codehilite">CapOptions</code> provides the following configuration items::</p> <p><code class="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 <code class="codehilite">FailedCallback</code> to handle failed messages. When the message fails to be sent multiple times, the CAP will mark the message state as <code class="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 <code class="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 <code class="codehilite">FailedCallback</code> to handle failed messages. When the message fails to be sent multiple times, the CAP will mark the message state as <code class="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 <code class="codehilite">FailedCallback</code> has a value, this callback function will be called first to tell the client.</p>
<p>The type of FailedCallback is <code class="codehilite">Action&lt;MessageType,string,string&gt;</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 <code class="codehilite">Action&lt;MessageType,string,string&gt;</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>
<h3 id="rabbitmq-options">RabbitMQ Options<a class="headerlink" href="#rabbitmq-options" title="Permanent link">&para;</a></h3> <h2 id="rabbitmq-configs">RabbitMQ Configs<a class="headerlink" href="#rabbitmq-configs" title="Permanent link">&para;</a></h2>
<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><div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; { <p><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; {
capOptions.UseRabbitMQ(rabbitMQOption=&gt;{ capOptions.UseRabbitMQ(rabbitMQOption=&gt;{
// rabbitmq options. // rabbitmq options.
}); });
}); });
</pre></div> </pre></div>
</td></tr></table>
<code class="codehilite">RabbitMQOptions</code> provides related RabbitMQ configuration:</p> <code class="codehilite">RabbitMQOptions</code> provides related RabbitMQ configuration:</p>
<table> <table>
<thead> <thead>
...@@ -921,21 +919,33 @@ ...@@ -921,21 +919,33 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<h3 id="kafka-options">Kafka Options<a class="headerlink" href="#kafka-options" title="Permanent link">&para;</a></h3> <h3 id="kafka-configs">Kafka Configs<a class="headerlink" href="#kafka-configs" title="Permanent link">&para;</a></h3>
<p>CAP adopts Kafka's configuration function to expand CapOptions, so the configuration usage for Kafka is as follows:</p> <p>CAP adopts Kafka's configuration function to expand CapOptions, so the configuration usage for Kafka is as follows:</p>
<div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; { <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5
6</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; {
capOptions.UseKafka(kafkaOption=&gt;{ capOptions.UseKafka(kafkaOption=&gt;{
// kafka options. // kafka options.
// kafkaOptions.MainConfig.Add(&quot;&quot;, &quot;&quot;); // kafkaOptions.MainConfig.Add(&quot;&quot;, &quot;&quot;);
}); });
}); });
</pre></div> </pre></div>
</td></tr></table>
<p><code class="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><code class="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><a href="https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md">https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md</a></p> <p><a href="https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md">https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md</a></p>
<h3 id="entityframework-options">EntityFramework Options<a class="headerlink" href="#entityframework-options" title="Permanent link">&para;</a></h3> <h3 id="entityframework-configs">EntityFramework Configs<a class="headerlink" href="#entityframework-configs" title="Permanent link">&para;</a></h3>
<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>
<div class="codehilite"><pre><span></span>services.AddCap(x =&gt; <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(x =&gt;
{ {
x.UseEntityFramework&lt;AppDbContext&gt;(efOption =&gt; x.UseEntityFramework&lt;AppDbContext&gt;(efOption =&gt;
{ {
...@@ -943,6 +953,7 @@ ...@@ -943,6 +953,7 @@
}); });
}); });
</pre></div> </pre></div>
</td></tr></table>
<p>Note that if you use the <code class="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 <code class="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>
<table> <table>
...@@ -975,15 +986,20 @@ ...@@ -975,15 +986,20 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<h3 id="sqlserver-options">SqlServer Options<a class="headerlink" href="#sqlserver-options" title="Permanent link">&para;</a></h3> <h3 id="sqlserver-configs">SqlServer Configs<a class="headerlink" href="#sqlserver-configs" title="Permanent link">&para;</a></h3>
<p>Note that if you are using EntityFramewrok, you do not use this configuration item.</p> <p>Note that if you are using EntityFramewrok, you do not use this configuration item.</p>
<p>CAP adopts the configuration function of SqlServer for extending CapOptions. Therefore, the configuration usage of SqlServer is as follows:</p> <p>CAP adopts the configuration function of SqlServer for extending CapOptions. Therefore, the configuration usage of SqlServer is as follows:</p>
<div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; { <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; {
capOptions.UseSqlServer(sqlserverOptions =&gt; { capOptions.UseSqlServer(sqlserverOptions =&gt; {
// sqlserverOptions.ConnectionString // sqlserverOptions.ConnectionString
}); });
}); });
</pre></div> </pre></div>
</td></tr></table>
<table> <table>
<thead> <thead>
...@@ -1009,15 +1025,20 @@ ...@@ -1009,15 +1025,20 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<h3 id="mysql-options">MySql Options<a class="headerlink" href="#mysql-options" title="Permanent link">&para;</a></h3> <h3 id="mysql-configs">MySql Configs<a class="headerlink" href="#mysql-configs" title="Permanent link">&para;</a></h3>
<p>Note that if you are using EntityFramewrok, you do not use this configuration item.</p> <p>Note that if you are using EntityFramewrok, you do not use this configuration item.</p>
<p>CAP uses the configuration function for MySql that extends for CapOptions, so the configuration usage for MySql is as follows:</p> <p>CAP uses the configuration function for MySql that extends for CapOptions, so the configuration usage for MySql is as follows:</p>
<div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; { <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>services.AddCap(capOptions =&gt; {
capOptions.UseMySql(mysqlOptions =&gt; { capOptions.UseMySql(mysqlOptions =&gt; {
// mysqlOptions.ConnectionString // mysqlOptions.ConnectionString
}); });
}); });
</pre></div> </pre></div>
</td></tr></table>
<table> <table>
<thead> <thead>
...@@ -1043,15 +1064,20 @@ ...@@ -1043,15 +1064,20 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<h3 id="postgresql-options">PostgreSql Options<a class="headerlink" href="#postgresql-options" title="Permanent link">&para;</a></h3> <h3 id="postgresql-configs">PostgreSql Configs<a class="headerlink" href="#postgresql-configs" title="Permanent link">&para;</a></h3>
<p>Note that if you are using EntityFramewrok, you do not use this configuration item.</p> <p>Note that if you are using EntityFramewrok, you do not use this configuration item.</p>
<p>CAP uses PostgreSql configuration functions for CapOptions extensions, so the configuration usage for PostgreSql is as follows:</p> <p>CAP uses PostgreSql configuration functions for CapOptions extensions, so the configuration usage for PostgreSql is as follows:</p>
<div class="codehilite"><pre><span></span><span class="n">services</span><span class="p">.</span><span class="n">AddCap</span><span class="p">(</span><span class="n">capOptions</span> <span class="p">=&gt;</span> <span class="p">{</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="n">services</span><span class="p">.</span><span class="n">AddCap</span><span class="p">(</span><span class="n">capOptions</span> <span class="p">=&gt;</span> <span class="p">{</span>
<span class="n">capOptions</span><span class="p">.</span><span class="n">UsePostgreSql</span><span class="p">(</span><span class="n">postgreOptions</span> <span class="p">=&gt;</span> <span class="p">{</span> <span class="n">capOptions</span><span class="p">.</span><span class="n">UsePostgreSql</span><span class="p">(</span><span class="n">postgreOptions</span> <span class="p">=&gt;</span> <span class="p">{</span>
<span class="c1">// postgreOptions.ConnectionString</span> <span class="c1">// postgreOptions.ConnectionString</span>
<span class="p">});</span> <span class="p">});</span>
<span class="p">});</span> <span class="p">});</span>
</pre></div> </pre></div>
</td></tr></table>
<table> <table>
<thead> <thead>
...@@ -1112,7 +1138,7 @@ ...@@ -1112,7 +1138,7 @@
</a> </a>
<a href="../design-principle/" title="Design Principle" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> <a href="../design/" title="Design Principle" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> <div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis"> <span class="md-flex__ellipsis">
<span class="md-footer-nav__direction"> <span class="md-footer-nav__direction">
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<meta name="description" content="Project documentation with Markdown."> <meta name="description" content="Project documentation with Markdown.">
<link rel="canonical" href="https://cap.dotnet-chain.org/user-guide/design-principle/"> <link rel="canonical" href="https://cap.dotnet-chain.org/user-guide/design/">
<meta name="author" content="CAP Team"> <meta name="author" content="CAP Team">
...@@ -108,7 +108,7 @@ ...@@ -108,7 +108,7 @@
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off"> <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label> <label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="#design-principle" tabindex="1" class="md-skip"> <a href="#design" tabindex="1" class="md-skip">
Skip to content Skip to content
</a> </a>
...@@ -386,6 +386,8 @@ ...@@ -386,6 +386,8 @@
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc"> <input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc"> <label class="md-nav__link md-nav__link--active" for="__toc">
Design Principle Design Principle
...@@ -399,50 +401,39 @@ ...@@ -399,50 +401,39 @@
<nav class="md-nav md-nav--secondary"> <nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label> <label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#design-principle" title="Design Principle" class="md-nav__link">
Design Principle
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#motivation" title="Motivation" class="md-nav__link"> <a href="#motivation" title="Motivation" class="md-nav__link">
Motivation Motivation
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#persistence" title="Persistence" class="md-nav__link"> <a href="#persistence" title="Persistence" class="md-nav__link">
Persistence Persistence
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#communication-data-streams" title="Communication Data Streams" class="md-nav__link"> <a href="#communication-data-streams" title="Communication Data Streams" class="md-nav__link">
Communication Data Streams Communication Data Streams
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#consistency" title="Consistency" class="md-nav__link"> <a href="#consistency" title="Consistency" class="md-nav__link">
Consistency Consistency
</a> </a>
</li> </li>
</ul>
</nav>
</li>
...@@ -461,7 +452,7 @@ ...@@ -461,7 +452,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -473,7 +464,7 @@ ...@@ -473,7 +464,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -678,50 +669,39 @@ ...@@ -678,50 +669,39 @@
<nav class="md-nav md-nav--secondary"> <nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label> <label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#design-principle" title="Design Principle" class="md-nav__link">
Design Principle
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#motivation" title="Motivation" class="md-nav__link"> <a href="#motivation" title="Motivation" class="md-nav__link">
Motivation Motivation
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#persistence" title="Persistence" class="md-nav__link"> <a href="#persistence" title="Persistence" class="md-nav__link">
Persistence Persistence
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#communication-data-streams" title="Communication Data Streams" class="md-nav__link"> <a href="#communication-data-streams" title="Communication Data Streams" class="md-nav__link">
Communication Data Streams Communication Data Streams
</a> </a>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#consistency" title="Consistency" class="md-nav__link"> <a href="#consistency" title="Consistency" class="md-nav__link">
Consistency Consistency
</a> </a>
</li> </li>
</ul>
</nav>
</li>
...@@ -739,17 +719,15 @@ ...@@ -739,17 +719,15 @@
<article class="md-content__inner md-typeset"> <article class="md-content__inner md-typeset">
<a href="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/design-principle.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a> <a href="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/design.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a>
<h1>Design Principle</h1>
<h2 id="design-principle">Design Principle<a class="headerlink" href="#design-principle" title="Permanent link">&para;</a></h2> <h1 id="design">Design<a class="headerlink" href="#design" title="Permanent link">&para;</a></h1>
<h3 id="motivation">Motivation<a class="headerlink" href="#motivation" title="Permanent link">&para;</a></h3> <h2 id="motivation">Motivation<a class="headerlink" href="#motivation" title="Permanent link">&para;</a></h2>
<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>
<h3 id="persistence">Persistence<a class="headerlink" href="#persistence" title="Permanent link">&para;</a></h3> <h2 id="persistence">Persistence<a class="headerlink" href="#persistence" title="Permanent link">&para;</a></h2>
<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>
<h3 id="communication-data-streams">Communication Data Streams<a class="headerlink" href="#communication-data-streams" title="Permanent link">&para;</a></h3> <h2 id="communication-data-streams">Communication Data Streams<a class="headerlink" href="#communication-data-streams" title="Permanent link">&para;</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>&gt;2.2 version before</p> <p>&gt;2.2 version before</p>
<p><img alt="" src="http://images2017.cnblogs.com/blog/250417/201708/250417-20170803174645928-1813351415.png" /></p> <p><img alt="" src="http://images2017.cnblogs.com/blog/250417/201708/250417-20170803174645928-1813351415.png" /></p>
...@@ -768,7 +746,7 @@ ...@@ -768,7 +746,7 @@
</blockquote> </blockquote>
<p><strong>After version 2.2</strong></p> <p><strong>After version 2.2</strong></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: <a href="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: <a href="https://github.com/dotnetcore/CAP/issues/96">Improve the implementation mechanism of queue mode</a></p>
<h3 id="consistency">Consistency<a class="headerlink" href="#consistency" title="Permanent link">&para;</a></h3> <h2 id="consistency">Consistency<a class="headerlink" href="#consistency" title="Permanent link">&para;</a></h2>
<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>
...@@ -810,7 +788,7 @@ ...@@ -810,7 +788,7 @@
</a> </a>
<a href="../implementation-mechanisms/" title="Implementation Mechanisms" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> <a href="../implementation/" title="Implementation Mechanisms" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> <div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis"> <span class="md-flex__ellipsis">
<span class="md-footer-nav__direction"> <span class="md-footer-nav__direction">
......
...@@ -381,7 +381,7 @@ ...@@ -381,7 +381,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../design-principle/" title="Design Principle" class="md-nav__link"> <a href="../design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -393,7 +393,7 @@ ...@@ -393,7 +393,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -405,7 +405,7 @@ ...@@ -405,7 +405,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -422,6 +422,8 @@ ...@@ -422,6 +422,8 @@
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc"> <input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc"> <label class="md-nav__link md-nav__link--active" for="__toc">
FAQ FAQ
...@@ -435,50 +437,39 @@ ...@@ -435,50 +437,39 @@
<nav class="md-nav md-nav--secondary"> <nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label> <label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#faq" title="FAQ" class="md-nav__link">
FAQ
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#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"> <a href="#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>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#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"> <a href="#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>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#how-to-use-the-same-database-for-different-programs" title="How to use the same database for different programs?" class="md-nav__link"> <a href="#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>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#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"> <a href="#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 @@
<nav class="md-nav md-nav--secondary"> <nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label> <label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#faq" title="FAQ" class="md-nav__link">
FAQ
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#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"> <a href="#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>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#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"> <a href="#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>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#how-to-use-the-same-database-for-different-programs" title="How to use the same database for different programs?" class="md-nav__link"> <a href="#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>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#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"> <a href="#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 @@
<a href="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/faq.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a> <a href="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/faq.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a>
<h1>FAQ</h1> <h1 id="faq">FAQ<a class="headerlink" href="#faq" title="Permanent link">&para;</a></h1>
<h2 id="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?<a class="headerlink" href="#any-im-groupeg-tencent-qq-group-to-learn-and-chat-about-cap" title="Permanent link">&para;</a></h2>
<h2 id="faq">FAQ<a class="headerlink" href="#faq" title="Permanent link">&para;</a></h2>
<h3 id="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?<a class="headerlink" href="#any-im-groupeg-tencent-qq-group-to-learn-and-chat-about-cap" title="Permanent link">&para;</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>
<h3 id="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 class="headerlink" href="#does-it-require-certain-different-databases-one-each-for-productor-and-resumer-in-cap" title="Permanent link">&para;</a></h3> <h2 id="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 class="headerlink" href="#does-it-require-certain-different-databases-one-each-for-productor-and-resumer-in-cap" title="Permanent link">&para;</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&amp;A below.</p> <p>Otherwise, look at Q&amp;A below.</p>
<h3 id="how-to-use-the-same-database-for-different-programs">How to use the same database for different programs?<a class="headerlink" href="#how-to-use-the-same-database-for-different-programs" title="Permanent link">&para;</a></h3> <h2 id="how-to-use-the-same-database-for-different-programs">How to use the same database for different programs?<a class="headerlink" href="#how-to-use-the-same-database-for-different-programs" title="Permanent link">&para;</a></h2>
<p>defining a prefix name of table in <code class="codehilite">ConfigureServices</code> method。</p> <p>defining a prefix name of table in <code class="codehilite">ConfigureServices</code> method。</p>
<p>codes exsample:</p> <p>codes exsample:</p>
<div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">void</span> <span class="nf">ConfigureServices</span><span class="p">(</span><span class="n">IServiceCollection</span> <span class="n">services</span><span class="p">)</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span> 1
2
3
4
5
6
7
8
9
10
11
12</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">void</span> <span class="nf">ConfigureServices</span><span class="p">(</span><span class="n">IServiceCollection</span> <span class="n">services</span><span class="p">)</span>
<span class="p">{</span> <span class="p">{</span>
<span class="n">services</span><span class="p">.</span><span class="n">AddCap</span><span class="p">(</span><span class="n">x</span> <span class="p">=&gt;</span> <span class="n">services</span><span class="p">.</span><span class="n">AddCap</span><span class="p">(</span><span class="n">x</span> <span class="p">=&gt;</span>
<span class="p">{</span> <span class="p">{</span>
...@@ -766,9 +755,13 @@ ...@@ -766,9 +755,13 @@
<span class="p">});</span> <span class="p">});</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<p>NOTE:different prefixed names cause SLB to no effect.</p> <div class="admonition note">
<h3 id="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.<a class="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">&para;</a></h3> <p class="admonition-title">Note</p>
<p>Different prefixed names cause SLB to no effect.</p>
</div>
<h2 id="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.<a class="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">&para;</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>
...@@ -791,7 +784,7 @@ ...@@ -791,7 +784,7 @@
<div class="md-footer-nav"> <div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid"> <nav class="md-footer-nav__inner md-grid">
<a href="../distributed-transactions/" title="Distributed Transactions" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> <a href="../transaction/" title="Distributed Transactions" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink"> <div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> <i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div> </div>
......
...@@ -108,7 +108,7 @@ ...@@ -108,7 +108,7 @@
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off"> <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label> <label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="#introduction" tabindex="1" class="md-skip"> <a href="#getting-stared" tabindex="1" class="md-skip">
Skip to content Skip to content
</a> </a>
...@@ -473,7 +473,7 @@ ...@@ -473,7 +473,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../design-principle/" title="Design Principle" class="md-nav__link"> <a href="../design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -485,7 +485,7 @@ ...@@ -485,7 +485,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -497,7 +497,7 @@ ...@@ -497,7 +497,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -788,8 +788,7 @@ ...@@ -788,8 +788,7 @@
<a href="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/getting-started.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a> <a href="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/getting-started.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a>
<h1 id="introduction">Introduction<a class="headerlink" href="#introduction" title="Permanent link">&para;</a></h1> <h1 id="getting-stared">Getting Stared<a class="headerlink" href="#getting-stared" title="Permanent link">&para;</a></h1>
<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>
<h2 id="usage-scenarios">Usage Scenarios<a class="headerlink" href="#usage-scenarios" title="Permanent link">&para;</a></h2> <h2 id="usage-scenarios">Usage Scenarios<a class="headerlink" href="#usage-scenarios" title="Permanent link">&para;</a></h2>
<p>The usage scenarios of CAP mainly include the following two:</p> <p>The usage scenarios of CAP mainly include the following two:</p>
<div class="bs-callout bs-callout-primary"> <div class="bs-callout bs-callout-primary">
...@@ -814,17 +813,27 @@ The CAP uses the local message table to persist the messages in the EventBus. Th ...@@ -814,17 +813,27 @@ The CAP uses the local message table to persist the messages in the EventBus. Th
<h2 id="quick-start">Quick Start<a class="headerlink" href="#quick-start" title="Permanent link">&para;</a></h2> <h2 id="quick-start">Quick Start<a class="headerlink" href="#quick-start" title="Permanent link">&para;</a></h2>
<h3 id="nuget-package">NuGet Package<a class="headerlink" href="#nuget-package" title="Permanent link">&para;</a></h3> <h3 id="nuget-package">NuGet Package<a class="headerlink" href="#nuget-package" title="Permanent link">&para;</a></h3>
<p>Use the following command to reference the CAP NuGet package:</p> <p>Use the following command to reference the CAP NuGet package:</p>
<div class="codehilite"><pre><span></span>PM&gt; Install-Package DotNetCore.CAP <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>PM&gt; Install-Package DotNetCore.CAP
</pre></div> </pre></div>
</td></tr></table>
<p>According to the different types of message queues used, different extension packages are introduced:</p> <p>According to the different types of message queues used, different extension packages are introduced:</p>
<div class="codehilite"><pre><span></span>PM&gt; Install-Package DotNetCore.CAP.RabbitMQ <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>PM&gt; Install-Package DotNetCore.CAP.RabbitMQ
PM&gt; Install-Package DotNetCore.CAP.Kafka PM&gt; Install-Package DotNetCore.CAP.Kafka
</pre></div> </pre></div>
</td></tr></table>
<p>According to the different types of databases used, different extension packages are introduced:</p> <p>According to the different types of databases used, different extension packages are introduced:</p>
<div class="codehilite"><pre><span></span>PM&gt; Install-Package DotNetCore.CAP.SqlServer <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>PM&gt; Install-Package DotNetCore.CAP.SqlServer
PM&gt; Install-Package DotNetCore.CAP.MySql PM&gt; Install-Package DotNetCore.CAP.MySql
...@@ -832,10 +841,38 @@ PM&gt; Install-Package DotNetCore.CAP.PostgreSql ...@@ -832,10 +841,38 @@ PM&gt; Install-Package DotNetCore.CAP.PostgreSql
PM&gt; Install-Package DotNetCore.CAP.MongoDB PM&gt; Install-Package DotNetCore.CAP.MongoDB
</pre></div> </pre></div>
</td></tr></table>
<h3 id="startup-configuration">Startup Configuration<a class="headerlink" href="#startup-configuration" title="Permanent link">&para;</a></h3> <h3 id="startup-configuration">Startup Configuration<a class="headerlink" href="#startup-configuration" title="Permanent link">&para;</a></h3>
<p>In an ASP.NET Core program, you can configure the services used by the CAP in the <code class="codehilite">Startup.cs</code> file <code class="codehilite">ConfigureServices()</code>:</p> <p>In an ASP.NET Core program, you can configure the services used by the CAP in the <code class="codehilite">Startup.cs</code> file <code class="codehilite">ConfigureServices()</code>:</p>
<div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">void</span> <span class="nf">ConfigureServices</span><span class="p">(</span><span class="n">IServiceCollection</span> <span class="n">services</span><span class="p">)</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">void</span> <span class="nf">ConfigureServices</span><span class="p">(</span><span class="n">IServiceCollection</span> <span class="n">services</span><span class="p">)</span>
<span class="p">{</span> <span class="p">{</span>
<span class="c1">//......</span> <span class="c1">//......</span>
...@@ -864,11 +901,49 @@ PM&gt; Install-Package DotNetCore.CAP.MongoDB ...@@ -864,11 +901,49 @@ PM&gt; Install-Package DotNetCore.CAP.MongoDB
<span class="p">});</span> <span class="p">});</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<h3 id="usage">Usage<a class="headerlink" href="#usage" title="Permanent link">&para;</a></h3> <h3 id="usage">Usage<a class="headerlink" href="#usage" title="Permanent link">&para;</a></h3>
<h4 id="publish">Publish<a class="headerlink" href="#publish" title="Permanent link">&para;</a></h4> <h4 id="publish">Publish<a class="headerlink" href="#publish" title="Permanent link">&para;</a></h4>
<p>Inject <code class="codehilite">ICapPublisher</code> in your Controller, then use the <code class="codehilite">ICapPublisher</code> to send message</p> <p>Inject <code class="codehilite">ICapPublisher</code> in your Controller, then use the <code class="codehilite">ICapPublisher</code> to send message</p>
<div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">class</span> <span class="nc">PublishController</span> <span class="p">:</span> <span class="n">Controller</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">class</span> <span class="nc">PublishController</span> <span class="p">:</span> <span class="n">Controller</span>
<span class="p">{</span> <span class="p">{</span>
<span class="k">private</span> <span class="k">readonly</span> <span class="n">ICapPublisher</span> <span class="n">_capBus</span><span class="p">;</span> <span class="k">private</span> <span class="k">readonly</span> <span class="n">ICapPublisher</span> <span class="n">_capBus</span><span class="p">;</span>
...@@ -907,11 +982,19 @@ PM&gt; Install-Package DotNetCore.CAP.MongoDB ...@@ -907,11 +982,19 @@ PM&gt; Install-Package DotNetCore.CAP.MongoDB
<span class="p">}</span> <span class="p">}</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<h4 id="subscribe">Subscribe<a class="headerlink" href="#subscribe" title="Permanent link">&para;</a></h4> <h4 id="subscribe">Subscribe<a class="headerlink" href="#subscribe" title="Permanent link">&para;</a></h4>
<p><strong>In Controller Action</strong></p> <p><strong>In Controller Action</strong></p>
<p>Add the Attribute <code class="codehilite">[CapSubscribe()]</code> on Action to subscribe message:</p> <p>Add the Attribute <code class="codehilite">[CapSubscribe()]</code> on Action to subscribe message:</p>
<div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">class</span> <span class="nc">PublishController</span> <span class="p">:</span> <span class="n">Controller</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">class</span> <span class="nc">PublishController</span> <span class="p">:</span> <span class="n">Controller</span>
<span class="p">{</span> <span class="p">{</span>
<span class="na"> [CapSubscribe(&quot;xxx.services.show.time&quot;)]</span> <span class="na"> [CapSubscribe(&quot;xxx.services.show.time&quot;)]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">CheckReceivedMessage</span><span class="p">(</span><span class="n">DateTime</span> <span class="n">datetime</span><span class="p">)</span> <span class="k">public</span> <span class="k">void</span> <span class="nf">CheckReceivedMessage</span><span class="p">(</span><span class="n">DateTime</span> <span class="n">datetime</span><span class="p">)</span>
...@@ -920,10 +1003,25 @@ PM&gt; Install-Package DotNetCore.CAP.MongoDB ...@@ -920,10 +1003,25 @@ PM&gt; Install-Package DotNetCore.CAP.MongoDB
<span class="p">}</span> <span class="p">}</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<p><strong>In Business Logic Service</strong></p> <p><strong>In Business Logic Service</strong></p>
<p>If your subscribe method is not in the Controller, the service class you need to Inheritance <code class="codehilite">ICapSubscribe</code>:</p> <p>If your subscribe method is not in the Controller, the service class you need to Inheritance <code class="codehilite">ICapSubscribe</code>:</p>
<div class="codehilite"><pre><span></span><span class="k">namespace</span> <span class="nn">BusinessCode.Service</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">namespace</span> <span class="nn">BusinessCode.Service</span>
<span class="p">{</span> <span class="p">{</span>
<span class="k">public</span> <span class="k">interface</span> <span class="n">ISubscriberService</span> <span class="k">public</span> <span class="k">interface</span> <span class="n">ISubscriberService</span>
<span class="p">{</span> <span class="p">{</span>
...@@ -939,9 +1037,19 @@ PM&gt; Install-Package DotNetCore.CAP.MongoDB ...@@ -939,9 +1037,19 @@ PM&gt; Install-Package DotNetCore.CAP.MongoDB
<span class="p">}</span> <span class="p">}</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
<p>Then inject your <code class="codehilite">ISubscriberService</code> class in <code class="codehilite">Startup.cs</code></p> <p>Then inject your <code class="codehilite">ISubscriberService</code> class in <code class="codehilite">Startup.cs</code></p>
<div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">void</span> <span class="nf">ConfigureServices</span><span class="p">(</span><span class="n">IServiceCollection</span> <span class="n">services</span><span class="p">)</span> <table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span> 1
2
3
4
5
6
7
8
9
10</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">public</span> <span class="k">void</span> <span class="nf">ConfigureServices</span><span class="p">(</span><span class="n">IServiceCollection</span> <span class="n">services</span><span class="p">)</span>
<span class="p">{</span> <span class="p">{</span>
<span class="c1">//Note: The injection of services needs before of `services.AddCap()`</span> <span class="c1">//Note: The injection of services needs before of `services.AddCap()`</span>
<span class="n">services</span><span class="p">.</span><span class="n">AddTransient</span><span class="p">&lt;</span><span class="n">ISubscriberService</span><span class="p">,</span><span class="n">SubscriberService</span><span class="p">&gt;();</span> <span class="n">services</span><span class="p">.</span><span class="n">AddTransient</span><span class="p">&lt;</span><span class="n">ISubscriberService</span><span class="p">,</span><span class="n">SubscriberService</span><span class="p">&gt;();</span>
...@@ -952,6 +1060,7 @@ PM&gt; Install-Package DotNetCore.CAP.MongoDB ...@@ -952,6 +1060,7 @@ PM&gt; Install-Package DotNetCore.CAP.MongoDB
<span class="p">});</span> <span class="p">});</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</td></tr></table>
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<meta name="description" content="Project documentation with Markdown."> <meta name="description" content="Project documentation with Markdown.">
<link rel="canonical" href="https://cap.dotnet-chain.org/user-guide/implementation-mechanisms/"> <link rel="canonical" href="https://cap.dotnet-chain.org/user-guide/implementation/">
<meta name="author" content="CAP Team"> <meta name="author" content="CAP Team">
...@@ -108,7 +108,7 @@ ...@@ -108,7 +108,7 @@
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off"> <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label> <label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="#message-table" tabindex="1" class="md-skip"> <a href="#implementation" tabindex="1" class="md-skip">
Skip to content Skip to content
</a> </a>
...@@ -381,7 +381,7 @@ ...@@ -381,7 +381,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../design-principle/" title="Design Principle" class="md-nav__link"> <a href="../design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -398,6 +398,8 @@ ...@@ -398,6 +398,8 @@
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc"> <input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc"> <label class="md-nav__link md-nav__link--active" for="__toc">
Implementation Mechanisms Implementation Mechanisms
...@@ -411,6 +413,8 @@ ...@@ -411,6 +413,8 @@
<nav class="md-nav md-nav--secondary"> <nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label> <label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
...@@ -423,8 +427,8 @@ ...@@ -423,8 +427,8 @@
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#message-format5" title="Message format5" class="md-nav__link"> <a href="#message-format" title="Message format" class="md-nav__link">
Message format5 Message format
</a> </a>
</li> </li>
...@@ -467,7 +471,7 @@ ...@@ -467,7 +471,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../distributed-transactions/" title="Distributed Transactions" class="md-nav__link"> <a href="../transaction/" title="Distributed Transactions" class="md-nav__link">
Distributed Transactions Distributed Transactions
</a> </a>
</li> </li>
...@@ -672,6 +676,8 @@ ...@@ -672,6 +676,8 @@
<nav class="md-nav md-nav--secondary"> <nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label> <label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
...@@ -684,8 +690,8 @@ ...@@ -684,8 +690,8 @@
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#message-format5" title="Message format5" class="md-nav__link"> <a href="#message-format" title="Message format" class="md-nav__link">
Message format5 Message format
</a> </a>
</li> </li>
...@@ -727,13 +733,12 @@ ...@@ -727,13 +733,12 @@
<article class="md-content__inner md-typeset"> <article class="md-content__inner md-typeset">
<a href="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/implementation-mechanisms.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a> <a href="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/implementation.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</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 <code class="codehilite">ConfigureServices</code> and <code class="codehilite">configure</code> method in the Startup.cs file,just like the way to initialize a <code class="codehilite">MiddleWare</code> in ASP.NET Core.</p> <h1 id="implementation">IMPLEMENTATION<a class="headerlink" href="#implementation" title="Permanent link">&para;</a></h1>
<h3 id="message-table">Message Table<a class="headerlink" href="#message-table" title="Permanent link">&para;</a></h3> <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 <code class="codehilite">ConfigureServices</code> and <code class="codehilite">configure</code> method in the Startup.cs file,just like the way to initialize a <code class="codehilite">MiddleWare</code> in ASP.NET Core.</p>
<h2 id="message-table">Message Table<a class="headerlink" href="#message-table" title="Permanent link">&para;</a></h2>
<p>After initialized, CAP will create two tables in the client side,they are <code class="codehilite">Cap.Published</code> and <code class="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 <code class="codehilite">Cap.Published</code> and <code class="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 <code class="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 <code class="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 <code class="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 <code class="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 <code class="codehilite">Failed</code> messages by default.</p> <p>Before version 2.2,CAP retry 100 times for <code class="codehilite">Failed</code> messages by default.</p>
</blockquote> </blockquote>
<h3 id="message-format5">Message format5<a class="headerlink" href="#message-format5" title="Permanent link">&para;</a></h3> <h2 id="message-format">Message format<a class="headerlink" href="#message-format" title="Permanent link">&para;</a></h2>
<p>CAP use JSON to transfer message,the following is CAP's messaging object model:</p> <p>CAP use JSON to transfer message,the following is CAP's messaging object model:</p>
<table> <table>
<thead> <thead>
...@@ -844,14 +849,14 @@ ...@@ -844,14 +849,14 @@
</tbody> </tbody>
</table> </table>
<p>CAP use the same algorithms as MongoDB ObjectId's distributed Id generation algorithms.</p> <p>CAP use the same algorithms as MongoDB ObjectId's distributed Id generation algorithms.</p>
<h3 id="eventbus">EventBus<a class="headerlink" href="#eventbus" title="Permanent link">&para;</a></h3> <h2 id="eventbus">EventBus<a class="headerlink" href="#eventbus" title="Permanent link">&para;</a></h2>
<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><img alt="" src="http://images2017.cnblogs.com/blog/250417/201708/250417-20170804153901240-1774287236.png" /></p> <p><img alt="" src="http://images2017.cnblogs.com/blog/250417/201708/250417-20170804153901240-1774287236.png" /></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><img alt="" src="https://camo.githubusercontent.com/452505edb71d41f2c1bd18907275b76291621e46/687474703a2f2f696d61676573323031352e636e626c6f67732e636f6d2f626c6f672f3235303431372f3230313730372f3235303431372d32303137303730353137353832373132382d313230333239313436392e706e67" /></p> <p><img alt="" src="https://camo.githubusercontent.com/452505edb71d41f2c1bd18907275b76291621e46/687474703a2f2f696d61676573323031352e636e626c6f67732e636f6d2f626c6f672f3235303431372f3230313730372f3235303431372d32303137303730353137353832373132382d313230333239313436392e706e67" /></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>
<h3 id="retry">Retry<a class="headerlink" href="#retry" title="Permanent link">&para;</a></h3> <h2 id="retry">Retry<a class="headerlink" href="#retry" title="Permanent link">&para;</a></h2>
<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 <code class="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 <code class="codehilite">Retry on sending</code>.</p>
<h3 id="data-clean-out">Data clean out<a class="headerlink" href="#data-clean-out" title="Permanent link">&para;</a></h3> <h2 id="data-clean-out">Data clean out<a class="headerlink" href="#data-clean-out" title="Permanent link">&para;</a></h2>
<p>table to store messages in database has an <code class="codehilite">ExpiresAt</code> field to mark the expiration time of the message. CAP will set <code class="codehilite">ExpiresAt</code> value as <strong>1 hour</strong> for <code class="codehilite">Successed</code> messages and <strong>15days</strong> for <code class="codehilite">Failed</code> messages.</p> <p>table to store messages in database has an <code class="codehilite">ExpiresAt</code> field to mark the expiration time of the message. CAP will set <code class="codehilite">ExpiresAt</code> value as <strong>1 hour</strong> for <code class="codehilite">Successed</code> messages and <strong>15days</strong> for <code class="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 <code class="codehilite">ExpiresAt</code> field's value isn't null and samller than current time.That is, <code class="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 <code class="codehilite">ExpiresAt</code> field's value isn't null and samller than current time.That is, <code class="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>
...@@ -884,7 +889,7 @@ ...@@ -884,7 +889,7 @@
<div class="md-footer-nav"> <div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid"> <nav class="md-footer-nav__inner md-grid">
<a href="../design-principle/" title="Design Principle" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> <a href="../design/" title="Design Principle" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink"> <div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> <i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div> </div>
...@@ -899,7 +904,7 @@ ...@@ -899,7 +904,7 @@
</a> </a>
<a href="../distributed-transactions/" title="Distributed Transactions" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> <a href="../transaction/" title="Distributed Transactions" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> <div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis"> <span class="md-flex__ellipsis">
<span class="md-footer-nav__direction"> <span class="md-footer-nav__direction">
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<meta name="description" content="Project documentation with Markdown."> <meta name="description" content="Project documentation with Markdown.">
<link rel="canonical" href="https://cap.dotnet-chain.org/user-guide/distributed-transactions/"> <link rel="canonical" href="https://cap.dotnet-chain.org/user-guide/transaction/">
<meta name="author" content="CAP Team"> <meta name="author" content="CAP Team">
...@@ -108,7 +108,7 @@ ...@@ -108,7 +108,7 @@
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off"> <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label> <label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="#asynchronous-recovery-events" tabindex="1" class="md-skip"> <a href="#transaction" tabindex="1" class="md-skip">
Skip to content Skip to content
</a> </a>
...@@ -381,7 +381,7 @@ ...@@ -381,7 +381,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../design-principle/" title="Design Principle" class="md-nav__link"> <a href="../design/" title="Design Principle" class="md-nav__link">
Design Principle Design Principle
</a> </a>
</li> </li>
...@@ -393,7 +393,7 @@ ...@@ -393,7 +393,7 @@
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../implementation-mechanisms/" title="Implementation Mechanisms" class="md-nav__link"> <a href="../implementation/" title="Implementation Mechanisms" class="md-nav__link">
Implementation Mechanisms Implementation Mechanisms
</a> </a>
</li> </li>
...@@ -410,6 +410,8 @@ ...@@ -410,6 +410,8 @@
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc"> <input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc"> <label class="md-nav__link md-nav__link--active" for="__toc">
Distributed Transactions Distributed Transactions
...@@ -423,6 +425,8 @@ ...@@ -423,6 +425,8 @@
<nav class="md-nav md-nav--secondary"> <nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label> <label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
...@@ -644,6 +648,8 @@ ...@@ -644,6 +648,8 @@
<nav class="md-nav md-nav--secondary"> <nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label> <label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
...@@ -671,13 +677,12 @@ ...@@ -671,13 +677,12 @@
<article class="md-content__inner md-typeset"> <article class="md-content__inner md-typeset">
<a href="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/distributed-transactions.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a> <a href="https://github.com/dotnetcore/cap/edit/master/docs/user-guide/transaction.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a>
<h1>Distributed Transactions</h1>
<p>For the processing of distributed transactions, this CAP library matches the "Asynchronous recovery events" scenario.</p> <h1 id="transaction">Transaction<a class="headerlink" href="#transaction" title="Permanent link">&para;</a></h1>
<h3 id="asynchronous-recovery-events">Asynchronous recovery events<a class="headerlink" href="#asynchronous-recovery-events" title="Permanent link">&para;</a></h3> <p>For the processing of distributed transactions, this CAP library matches the "Asynchronous recovery events" scenario.</p>
<h2 id="asynchronous-recovery-events">Asynchronous recovery events<a class="headerlink" href="#asynchronous-recovery-events" title="Permanent link">&para;</a></h2>
<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>
...@@ -705,7 +710,7 @@ ...@@ -705,7 +710,7 @@
<div class="md-footer-nav"> <div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid"> <nav class="md-footer-nav__inner md-grid">
<a href="../implementation-mechanisms/" title="Implementation Mechanisms" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> <a href="../implementation/" title="Implementation Mechanisms" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink"> <div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> <i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment