简体   繁体   中英

Java concurrent counter architecture design

Having the following business case:

Email promotional campaign says that first 1_000_000 users pressing the link will receive a Bonus. Users are going to see either the Bonus or "Sorry" message immediately during visiting web page.

Question: how to design this solution?

  • Option 1: Monolith. AtomicInteger. Can the CAS issue take place here? Or 1_000_000 is not that amount that cause an issue in this case? What is the number which can "do" that?
  • Option 2: Monolith. sync should work here with no issues?
  • Option 3: Microservices. Redis INCR method. Is there are any options for microservices architecture? Is there a way to use MySql for this purpose?
  1. Plain Old Java: Use in-memory synchronization using java lock semantics. You are correct about using AtomicInteger. However, this can only work if you have only one application instance running.

  2. With MySql: There is a feature called select for update that helps you achieve what you are looking for. Whenever someone clicks on the link, you do select for update in MySql to see if the bonus is still available. If it is, you do update in DB in the same transaction. Meanwhile, all other parallel reads and writes will be blocked. Hence you get end-to-end fully atomic operation.

  3. Redis won't work because even if INCR is atomic, the whole flow of reading the value from Redis, performing the business logic, and updating the value in Redis won't be atomic. Eg Say the user count in Redis was 999_999 and 2 users concurrently click on the link. The application checks the count and it's under the threshold of 1_000_000 which means, both users are eligible for a discount and you end up giving a discount to both.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM