Avoid the use of message queues Distributed Transaction issues

Recently Alipay transfer from the balance of 10,000 yuan to the treasure, which is an ordinary little things of everyday life, but as an occupational Internet R & D personnel, I think Alipay after deducting 10,000, if the system hang up how to do, then PayPal account balance and no increase in 10000, the data will be inconsistent with the situation. Such a scenario can be found in each type similar to the shadow of the system, such as the electricity supplier system, when the single users, except in order to insert a record sheet, this table corresponding to the number of items of goods must be decremented by one ; in search advertising system, when a user clicks on an ad, in addition to a record increase in the click event table, the table had to go to find this merchant account and deduct business expenses such as advertising, I believe we can more or how much encountered similar scenarios. These problems are essentially abstracted as when a data update, how to ensure that data in another table must be updated successful problem-a transaction.

Local Services

A transaction is a mechanism in order to ensure the success of the same transaction or operation while at the same time fail. Or in Alipay transfer the balance of Po, for example, suppose you have PayPal account Table: A (id, userId, amount), the balance of PayPal account to the table: B (id, userId, amount), the user userId is 1, then you can from Alipay transfer Po 1 million dollars to balance the action is divided into two steps:

1) Alipay Table deduct 1 million.

update A set amount = amount - 10000 where userId = 1;

2) Balance sheet Bao increased by 1 million.

update B set amount = amount + 10000 where userId = 1;

How to ensure the balance of treasure Alipay balance it? Some say this is very simple thing, you can use the transaction to resolve.

Begin transaction
    update A set amount = amount - 10000 where userId = 1;
    update B set amount = amount + 10000 where userId = 1;
End transaction
commit;

Very correct! If you are using Spring then be able to get a @Transaction comment above transaction capabilities.

@Transactional(rollbackFor=Exception.class)
public void update() {
    updateATable(); // 更新A表
    updateBTable(); // 更新B表
}

If the system is smaller, data tables in a database instance on the local transaction can be a good way to run, but if a large-scale system, such as in the above scenario, the PayPal account PayPal account balances table and the table is clearly not on the same database instance, they are often distributed on different physical node, then local affairs has lost useless.

Since the failure of local transactions, distributed transactions naturally on stage.

Distributed Transaction - two-phase commit protocol

Two-phase commit protocol (Two-phase Commit, 2PC) are often used to implement a distributed transaction. And C is generally divided into a number of affairs coordinator performer Si two roles, where the performer is a specific transaction database, and transaction coordinator can execute in one machine.

1. Our application (client) initiates a request to start TC.

2.TC First <prepare> written to a local log message, and then initiates <prepare> message to all Si. Alipay transfer to balance Po, for example, TC A to prepare message is to inform the respective accounts database Alipay charge 1w, prepare message to the TC B is notified account balance Po increases corresponding database 1w. Why do I need to write before you perform the task local logs, mainly to the recovery by the local log plays real-life effect credentials, if there is no local log (voucher), easy to die without a check against.

After 3.Si receive <prepare> message, the machine to perform specific transactions, but does not commit, if successful return <yes>, unsuccessful returns <no>. Similarly, before returning to the message should be returned to the log in, as proof.

4.TC collect all the messages returned by the actuator, if the actuator return all Yes, then the commit message sent to all actuators occurs, the local transaction commit operations performed after the actuator receives commit; if there is no return of any one actuator then send abort message to all actuators to perform the operation after executing a transaction abort abort receives the message.

It is noted that, TC or Si to messages sent or received prior to the write log, mainly to use the recovery. After such a Si recovers from the failure, the machine check logs, if received <commit>, is submitted, if <abort> rollback. If <yes>, the TC ask again, determine the next step. If nothing, it is likely in the <prepare> Si stage collapsed, and therefore need to roll back.

Now Based on two-phase commit distributed transactions is not so difficult, if you are using Java, you can use open source software Atomikos ( http://www.atomikos.com/ ) to quickly implement.

Disadvantage of two-phase commit

But whenever the students have used two-phase commit can be found performance is really bad, is not suitable for highly concurrent systems.

1. Submit time involved in communication between multiple network nodes communicate too long in two stages.

2. Transaction time relative to longer, resource locking time becomes longer, resulting in increased waiting time a lot of resources.

It is because there is a very serious performance problems in distributed transactions, most of the high concurrent services are to avoid the use, often to solve the problem of data consistency through other means.

To avoid the use of message queues Distributed Transaction

If you look at life, then life scene has given us a lot of tips. For example, now go eat some of the food shops, is a window to the first meal pay, pay window to give you a voucher, then you go to another window to get meals based on this evidence. This approach has many benefits, one of the important benefits that can effectively prevent some people dined without paying, because without a valid certificate to take meals in the window, you will not take meals.

Or return to our problem, as long as this certificate, you ultimately eat your money to buy rice. Similarly transfer services, too, when the PayPal account to pay 10,000 deduction, as long as we generate a certificate (message) can be read, this certificate (news) [let PayPal account balance increase 1W], as long as the voucher (news) can reliable preservation, we can finally take this voucher (news) let PayPal account balance increase of 10,000, that we can rely on the certificate (message) to complete the final consistency.

Reliable Save the document (message)

In the example above life, if we take the meal vouchers lost, then we could not get the money to buy a meal. Similarly, if [let PayPal account balance increase 1W] of this certificate is not saved and is lost, it will result in losses. Therefore, to ensure reliable credentials to save it particularly important, there are two main methods:

Coupling mode with the message service

Alipay in complete charge at the same time, while recording the message data, the message data with business data stored in the same database instance in the (record-table called news message);

Begin transaction
    update A set amount = amount - 10000 where userId = 1;
    insert into message(userId, amount, status) values(1, 10000, 1);
End transaction
commit;

As long as the above transactions to ensure Alipay account the money deducted, the message will be able to survive.

When the above-mentioned transaction commits successfully, we treasure this message to inform balance, the balance of treasure after successfully processed successfully send a reply message, delete the article to pay Bao received a reply message data via real-time messaging service.

Business news and decoupled way

Such that the above-described manner saved message data and message service data tightly coupled together, Architecturally inelegant, and likely to cause other problems. To decouple, can be used in the following manner.

1. Alipay debit transaction before submitting a request to send a message to the instant messaging service, instant messaging service messages only record data, without actually sending the transaction will only be submitted after the message is sent successfully.

2. When Alipay debit transaction is committed successfully, send an acknowledgment to the real-time messaging service. Only after receiving confirmation instruction, real-time messaging service really send the message.

3. When the submission failed rollback Alipay debit transaction, cancel the service to send real-time messages. After obtaining the transmission cancellation command, the message will not be sent.

4. For those who have not acknowledged the message or cancel the message, you need to have a confirmation message status to pay for treasure system timing system query the status of the news and updates. Why do we need this step, for example: Suppose pay the treasure debit transaction is successfully submitted, the system hung up in step 2, this time the message status has not been updated to confirm [send], resulting in the message can not be sent.

Advantages: independently storing message data, reducing the coupling between the service system and the message system.

Disadvantages: a need to send two request message; service message processing services need to implement the interface state check back.

Repeat the message delivery problem

There is also a very serious problem is the repeated message delivered to us Alipay transfer to the balance of Po, for example, if the same message is repeated twice delivered, then we will increase the balance PayPal account 2w instead of 1w.

Why repeat the same message will be delivered? For example, the balance of treasure handling the messages msg, sent a message successfully processed to Alipay, under normal circumstances, Alipay should you want to delete the message msg, but if Alipay this time of tragedy hung up, a look at the message msg is still after the restart, it will continue send message msg.

The solution is simple, the increase in the balance of treasure here messaging application state table (message_apply), it is popular before the actual execution, go to a messaging application status books for consumption recorded message every time a message table query again, if the note is found duplicate messages can be discarded, if not found before execution, and inserted into the message application state table (the same transaction).

for each msg in queue
  Begin transaction
    select count(*) as cnt from message_apply where msg_id = msg.msg_id;
    if cnt == 0 then
      update B set amount = amount + 10000 where userId = 1;
      insert into message_apply(msg_id) values(msg.msg_id);
  End transaction
  commit;

Ebay researchers early in 2008 proposed the application message confirmation state table to solve the problem of delivering the message repeated: http://queue.acm.org/detail.cfm?id=1394128 .

 

"All the world is a long-awaited reunion encounter, and you do not return as scheduled, meaning this is the parting."

Guess you like

Origin www.cnblogs.com/yanggb/p/11818558.html