Objective
After 2 months of adjustment and testing, Cap 2.3 release finally released, this version of the biggest feature is the support for MongoDB, thanks to the blog Park team of Keke Students for MONGODB support provided by the PR, I believe with the use of the blog Park, CAP will be more and more help to more people.
The cap is an open source project solution (GITHUB.COM/DOTNETCORE/CAP) that solves the problem of distributed transactions in MicroServices or distributed systems, and is now nearly 2 years old, and the students who want to know more about CAP can look at my article.
Background story
In version 2.3, we made some adjustments to the API and why did we make these adjustments? I'll just take a look at the middle of this process.
I believe that the students in the CAP know that in 2.2 and previous versions there is a Bug that when a transaction is persisted to the database and if the transaction has not been committed, then the CAP will start sending messages to the message queue, but one problem is that if the subsequent transaction commits fail, This time the message has been sent out, it will cause the consumer to receive the message, corresponding to the GitHub issue.
This Bug to say serious also serious, to say is not serious is not serious, but we always have to solve this problem. How to solve it? Some students may say to change the sending message to the end of the transaction submission, but the CAP is unable to get the result of the transaction execution on the business side, because the. NET does not resemble spring transaction this mechanism can easily do some extensions, so if you want to change to a transaction commit, then you must provide an API to let the user manually call to send. This can be an easy solution to this problem, but I think this is a lot of code for the user, need to increase the cost of learning and more understanding of what is done within the framework, and may forget to call or use the wrong.
In order for the CAP's users to write down this line of code, I've been thinking about it for months and talking about the process.
For the database of the underlying driver of the code did know that the database driver in the underlying encapsulation of the special death, especially for the transaction of this piece of processing, the class is sealed almost no way to expand, I did some attempts to fail, and finally want to fork a database driver to modify the release of their own Nuget package, but this solution was eventually rejected, because I myself do not want to use their own compiled database driver, the end of the road is not feasible.
Another scenario is that a classmate who knows about diagnostics may have thought of this feature to track the outcome of a transactional submission, and then do some processing on it. But what's the problem? Currently only the SQL Server Driver Support Diagnostics, the other mysql,postgresql are not supported, how to do? It is impossible not to take care of those users who use Mysql,postgresql, after all, we are also using MYSQL.
Lemon and I have submitted to the MySQL and POSTGRESQL C # database project a PR (MySQL PR, POSTGRESQL PR) support for the diagnostics feature, but due to Microsoft's Diagnosticssource AP I design problems, resulting in the community of the way the API is more offensive, but also the guidance of some of the principles of the document, Microsoft in the SQLClient drive is not adhered to, so the two PR has not been merged, interested can also look at the discussion here, so do not know what to wait until when.
Another reason is that we need to dock the new MONGODB,MONGODB the processing of transactions is different in the API, and in order to provide a consistent user interface, some changes need to be made.
Above, we need to make adjustments to the API and we can't keep stalling. Let's take a look at the changes made in version 2.3.
Change in Cap 2.3 version 1, remove cap middleware registration
Now, you don't need to app.UseCap()
add the middleware manually, and we'll automatically register it.
In the previous version of 2.3, we need to register the CAP in startup Configure, and now we have automatically registered it at boot time you no longer need to register manually.
public void Configure(IApplicationBuilder app){ app.UseCap(); //移除了,不需要再手动注册}
2, modified the message table primary key type
In order to adapt the latest MongoDB and the data table migration under some scenes, we changed the primary key ID of the message table from the self-growing int type to the long type generated by the snowflake algorithm, which can improve the performance of message processing and the complexity of logic to some extent.
From the 2.2 upgrade, we provide a database migration script, you can view here to get the database migration script, and then the database execution.
Gist.github.com/yuleyule66/0e5ec7a5046dc58fcf89d51e4820c5cd
3, modified the Publish API
We have added a new ICapTransaction
interface to control transaction processing, and this is to deal with the situation where the transaction interface is not tracked, while we encapsulate a series of extension methods for developers to use, let's look at the new API
using (var session = _mongoClient.StartTransaction(_capBus, autoCommit: false)){ var collection = _mongoClient.GetDatabase("test").GetCollection<BsonDocument>("test.collection"); collection.InsertOne(session, new BsonDocument { { "hello", "world" } }); _capBus.Publish("sample.rabbitmq.mongodb", DateTime.Now); session.CommitTransaction();}
Here connection.StartTransaction
is an extension method, The extension method returns the IClientSessionHandle
interface , which represents the native transaction object of MongoDB, we can use this object when we are doing our own business code.
The reason for naming starttransaction is that we want to follow MongoDB's naming conventions, which make it easy for users to understand
using (var connection = new SqlConnection("")){ using (var transaction = connection.BeginTransaction(_capBus, autoCommit: false)) { //your business code sample connection.Execute("insert into test(name) values('test')", transaction); _capBus.Publish("sample.rabbitmq.sqlserver", DateTime.Now); transaction.Commit(); }}
Here connection.BeginTransaction
is an extension method, This extension method returns the IDbTransaction
interface , it represents the database of the native transaction object, we do our own business code to use this object to dapper or ADO.
using (var connection = new MySqlConnection("")){ using (var transaction = connection.BeginTransaction(_capBus, autoCommit: false)) { //your business code sample connection.Execute("insert into test(name) values('test')",transaction: (IDbTransaction)transaction.DbTransaction); _capBus.Publish("sample.rabbitmq.mysql", DateTime.Now); transaction.Commit(); }}
Here connection.BeginTransaction
is an extension method, This extension method returns the ICapTransaction
interface , the interface wrapper has the DbTransaction
attribute, it represents the database of the native transaction object, we do our own business code to use this object to dapper or ADO.
4. Added automatic transaction submission
In some cases, in order to streamline the code, we do not want to manually invoke the method to ask the transaction.Commit()
cap to help you commit the transaction, then you can do it, you just need to connection.BeginTransaction
pass the parameters at the time autoCommit
true
.
It is important to note that when using the Autocommit feature, you need to send a message after your business logic executes, meaning _capBus.Publish
that the line of code needs to be put to the last execution. Instance code:
using (var connection = new MySqlConnection("")){ using (var transaction = connection.BeginTransaction(_capBus, autoCommit: true)) { //your business code sample _capBus.Publish("sample.rabbitmq.mysql", DateTime.Now); }}
Attention here autoCommit: true
, and canceled.transaction.Commit()
5. Increased support for MongoDB
In micro-service applications, sometimes some of our services may be for performance or other reasons, the use of not traditional relational database, and some non-relational database, such as MongoDB as a representative, the use of the most people, Then there is the need to want to keep the data high consistency when storing the data.
MongoDB supports ACID transactions in versions 4.0 and above, which gives us reason to support MongoDB, while MongoDB support is also the Keke of the blog Park to provide the PR, thanks again.
Some students may want to try, then the following is simple to say, MongoDB support for acid business is required to use the cluster, so we need to first build a cluster, build clusters of articles I have written, we can refer to this blog to build.
After the cluster is built, you can configure it in the Startup.cs file ConfigureServices(IServiceCollection services)
.
public void ConfigureServices(IServiceCollection services){ services.AddSingleton<IMongoClient>(new MongoClient("mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0")); services.AddCap(x => { x.UseMongoDB("mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0"); x.UseRabbitMQ("localhost"); x.UseDashboard(); });}
How to use:
Note: MongoDB cannot create databases and collections in transactions, so if you create a cluster that is empty, you need to create the databases and collections separately, and you can simulate a record insert that is created automatically.
var mycollection = _client.GetDatabase("test").GetCollection<BsonDocument>("test.collection");mycollection.InsertOne(new BsonDocument { { "test", "test" } });
And then
[Route("~/without/transaction")]public IActionResult WithoutTransaction(){ _capBus.Publish("sample.rabbitmq.mongodb", DateTime.Now); return Ok();}[Route("~/transaction/not/autocommit")]public IActionResult PublishNotAutoCommit(){ //NOTE: before your test, your need to create database and collection at first using (var session = _client.StartTransaction(_capBus, autoCommit: true)) { var collection = _client.GetDatabase("test").GetCollection<BsonDocument>("test.collection"); collection.InsertOne(session, new BsonDocument { { "hello", "world" } }); _capBus.Publish("sample.rabbitmq.mongodb", DateTime.Now); } return Ok();}
Summarize
In the last month or two there has been a noticeable increase in the number of people using caps, and there have been a number of Cap blog posts in the Blog park, and we are happy to help you
。 We are in the process of using the problem and hope to be able to positive feedback, to help the cap become more and more good. :)
If you feel that this article is helpful to you, thank you for your "recommendation".
If you are interested in. NET Core, you can pay attention to me, I will regularly share my learning experience in the blog.
This article address: http://www.cnblogs.com/savorboard/p/cap-2-3.html
Author Blog: Savorboard
The original authorization for this article is: Attribution-NonCommercial use- Forbidden Deduction, agreement Plain text | Agreement Legal text