Skip to content

幂等性问题

常见幂等问题

解决常见幂等性问题采用 一锁、二判、三更新 就可以解决。

  • 一锁:锁定需要处理的订单
  • 二判:订单是否支付
  • 三更新:更新订单状态

数据库锁-悲观锁

  • for Update

    FOR UPDATE 子句告诉数据库管理系统(DBMS)在检索行的同时锁定这些行,直到当前事务结束。

java
BEGIN;

SELECT * FROM orders
WHERE order_id = 123
FOR UPDATE;

-- 进行业务逻辑处理,例如更新订单状态
UPDATE orders SET status = 'SHIPPED' WHERE order_id = 123;

COMMIT;

分布式锁

  • 可以用redis分布式锁

  • 也可以用zk分布式锁

    但是高并发场景,建议用redis的分布式锁,因为性能好。zk这种CP模型在高并发情况,因为糟糕的写效率性能会很差。

java
transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(@NonNull TransactionStatus status) {

                //一锁
                CommandRecord record = service.queryByLock(id);

                //二判
                if (CommandStatusEnum.SUCCESS != record.status()) {

                    //处理业务逻辑
                    process();
            
                    //三更新
                    //更新状态
                    record.setStatus(CommandStatusEnum.SUCCESS);
                    record.setSuccessTime(new Date());
                    commandRecordService.update(record);

                    log.info("CommandRecord execute success, commandRecord:{},response:{}",
                            record, JSON.toJSONString(response));
                }
            }

        });