Prevent repeated submission of orders or payment distributed lock scheme design

recommended reading

Project Practice: Best Practices for AI Text OCR Recognition

AI Gamma generates PPT tool direct link with one click

Play with cloud Studio, the online coding tool

Play with GPU AI painting, AI speech, and translation, GPU lights up the AI ​​imagination space

Information sharing

Sharing of the most complete documentation of AI painting stablediffusion in history

AI painting about SD, MJ, GPT, SDXL encyclopedia

AI painting stable diffusion Midjourney official GPT document AIGC encyclopedia data collection

「java、python面试题」来自UC网盘app分享,打开手机app,额外获得1T空间
https://drive.uc.cn/s/2aeb6c2dcedd4
AIGC资料包
https://drive.uc.cn/s/6077fc42116d4
https://pan.xunlei.com/s/VN_qC7kwpKFgKLto4KgP4Do_A1?pwd=7kbv#

In modern e-commerce applications, order submission and payment are one of the core business processes. However, due to various reasons, users may submit orders or make repeated payments multiple times, which may lead to serious problems such as inventory errors, multiple deductions, etc. In order to solve this problem, we can use distributed locks to ensure the uniqueness of orders. This article will introduce how to design and implement a distributed lock scheme that prevents repeated submission or payment of orders.

introduction

In a distributed system, when multiple nodes access shared resources at the same time, a mechanism is needed to ensure data consistency and uniqueness. Distributed locks are such a mechanism that can be used to coordinate access to shared resources by different nodes to prevent concurrency conflicts. In the scenario of order submission and payment, we need to ensure that the same order will not be submitted or paid multiple times, so a distributed lock is needed to protect the order data.

Distributed lock selection

Before designing a distributed lock solution, we need to choose a suitable distributed lock implementation. There are many ways to implement distributed locks, including database-based, cache-based, ZooKeeper-based, etc. In this article, we will use cache-based distributed locks because it has high performance and low latency and is suitable for order submission and payment scenarios.

We will use Redis as cache storage, because Redis is a high-performance in-memory database with distributed features, which can easily implement distributed locks.

Design a distributed lock solution

Step 1: Obtain the lock when the order is generated

When a user submits an order, the system first needs to generate a unique order number and try to obtain a distributed lock to lock the order number. If the lock is successfully obtained, it means that the order number has not been used, and you can continue to create orders; if the lock cannot be obtained, it means that the order number has been occupied by another user, and the user needs to be prompted to resubmit the order.

Here is a code example for acquiring a lock:

import redis

# 连接到Redis服务器
redis_client = redis.Redis(host='localhost', port=6379, db=0)

# 订单号
order_number = generate_order_number()

# 尝试获取锁
lock_key = f'order_lock:{
      
      order_number}'
lock_value = str(time.time())  # 使用当前时间作为锁的值
lock_acquired = redis_client.set(lock_key, lock_value, nx=True, ex=60)  # 设置锁的过期时间为60秒

if lock_acquired:
    # 获取锁成功,继续创建订单
    create_order(order_number)
else:
    # 获取锁失败,提示用户重新提交订单
    return "订单已经在处理中,请不要重复提交。"

In the above code, we first generate a unique order number, and then try to acquire a order_lock:{order_number}lock named , the value of the lock is the current timestamp, and the expiration time of the lock is set to 60 seconds. If the lock is acquired successfully, the order can continue to be created; if the acquisition fails, a prompt message is returned to the user.

Step 2: Obtain the lock when the order is paid

When the user pays for the order, the system needs to acquire the distributed lock again to ensure the uniqueness of the order. Similar to the logic when the order is generated, we use the order number as the key of the lock and try to acquire the lock. If the lock is acquired successfully, it means that the order can continue to be paid; if the acquisition fails, it means that the order is being paid by other users, and the user needs to be prompted to wait or pay again.

The following is a code example to obtain the lock when paying:

# 订单号
order_number = get_order_number_from_request()

# 尝试获取锁
lock_key = f'order_lock:{
      
      order_number}'
lock_value = str(time.time())  # 使用当前时间作为锁的值
lock_acquired = redis_client.set(lock_key, lock_value, nx=True, ex=60)  # 设置锁的过期时间为60秒

if lock_acquired:
    # 获取锁成功,继续支付订单
    process_payment(order_number)
else:
    # 获取锁失败,提示用户等待或重新支付
    return "订单正在支付中,请稍后或重新支付。"

Similarly, we use the order number as the key of the lock to try to acquire the lock. If the lock is acquired successfully, we can continue to pay for the order; if the acquisition fails, a prompt message is returned to the user.

Step 3: Release the lock

After the order is generated or the payment is completed, the lock needs to be released so that other users can use the same order number to operate. The code to release the lock is as follows:

# 订单号
order_number = get_order_number_from_request()

# 释放锁
lock_key = f'order_lock:{
      
      order_number}'
current_lock_value = redis_client.get(lock_key)

if current_lock_value and current_lock_value == lock_value:
    # 当前锁的值与之前设置的值相同,说明是当前用户的锁,可以释放
    redis_client.delete(lock_key)

When releasing the lock, we first obtain the value of the current lock and compare it with the previously set value. If they are the same, it means that the lock of the current user can be released.

Summarize

By using Redis-based distributed locks, we can effectively prevent the problem of repeated order submission or payment. When the order is generated and paid, by acquiring and releasing the lock, it can be ensured that the same order can only be operated by one user, thus ensuring the consistency and uniqueness of the order data.

In practical applications, we need to consider more details, such as error handling, timeout handling, etc., to ensure the stability and reliability of the system. At the same time, you can also consider using distributed transactions to further enhance data consistency.

Guess you like

Origin blog.csdn.net/weixin_42373241/article/details/132695685