Order service (distributed transaction)

After the user completes the payment, the payment status and order status will be saved in the order database, and the order database will be maintained by the order service. The student's course selection information is in the learning center database, and the learning service maintains the information in the learning center database. The following figure is a system structure diagram:

Insert picture description here


how to implement two distributed services (order service, learning service) to complete one thing together, that is, the successful order payment automatically adds the student's demand for course selection. The key here is how to ensure the transaction of the two distributed services Consistency.

The message queue implements the final consistent
CAP theory. Give up real-time consistency and ensure final consistency.
Create the order project xc-service-manage-order.
Create the order database xc_order (MySQL).

Insert picture description here


xc_orders: order master table
xc_orders_details: order detail table
xc_orders_pay: order payment table
xc_task: task table
xc_task_his: historical task table

Insert picture description here


The reliability of the production side refers to the solution of the cloud E office (above)

Consumer end idempotence The
monitored message message contains the message body and the message header. The msgId is obtained from UUID.randomUUID().toString(), which can guarantee the uniqueness of msgId (equivalent to the role of a token).

When you click to buy on the front end to enter the order page, it will request the order service to generate a msgId and return it to the front end. At the same time, the order service saves the msgId in Redis, redis.set("order:token:{userId}" ,"msgId"), the current When the client clicks submit, it will carry the msgId to request the order service again. The order service sends the msgId to the message queue. The learning service listens to the msgId and judges whether the token exists in redis. The existence indicates the first request, then delete the token and continue to execute the business. If it is judged that the token does not exist in redis, it means that it is a repeated operation, and the repeated mark is directly returned to the client, which ensures that the business code will not be executed repeatedly.

The msgId here can be understood as an order number. Why not generate msgId when submit is clicked on the front end? Assuming that the front end is stuck and you click submit multiple times, multiple different msgIds will be generated, but there should be only one order. Therefore, when the front-end opens the order page, the msgId must be generated, so that the msgId is the same after multiple clicks to submit.

Considering the high concurrency, the acquisition, comparison and deletion of Token (msgId) must be atomic . For example, if the front-end is clicked twice, two requests A and B are generated. A first gets msgId in Redis, and it has not had time to delete it. , B is also get, and the business will be operated twice, losing idempotence.
You can use lua scripts to complete this operation in redis:

if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end