首页 > 解决方案 > 如何在 laravel 中处理同时保存 API 请求?

问题描述

我正在尝试通过 API 保存新的预订。下面是保存预订功能的示例代码。

public function save_booking(Request $request){
        $booking = new Booking;
        $booking->booking_number            = generate_booking_id();
        $booking->booking_type              = $request->input('bookingType');
        $booking->booking_date              = $request->input('bookingDate');
        $booking->booking_time              = $request->input('bookingTime');
        $booking->booking_status            = $request->input('bookingStatus');
        $booking->save();
}

注意 - generate_booking_id() 是生成预订的辅助函数,如 BN-202105-0001(最后四位数字 0001 是通过从预订表中添加总记录数 + 1 来计算的)。

当两个或多个同时保存 API 请求尝试保存新预订时,会为这两个请求分配相同的预订编号。(例如请求 1 = BN-202105-0001,请求 2 = BN-202105-0001 等等。)

我想为每个同时发生的 API 请求分配不同的预订号。(例如,有 4 个同时请求尝试保存新预订,然后请求 1 = BN-202105-0001、请求 2 = BN-202105-0002、请求 3 = BN-202105-0003、请求 4 = BN-202105-0004)

如何解决 Laravel 中的并发请求问题?

提前致谢!

标签: phpdatabaselaravelapiconcurrency

解决方案


发生这种情况是因为您generate_booking_id()同时从两个不同的请求中读取数据库并为您生成预订 ID。

您可以避免这种情况,方法是ON INSERT在数据库级别创建一个触发器,如下所示booking_number为您更新而不是手动执行它。触发器将确保booking_number在创建预订之后而不是之前自动更新。

假设您使用的是 MySQL:(尽管如此,您可以在其他数据库管理系统中使用相同的方法)

CREATE TRIGGER 'bookings'.'update_booking_number'
AFTER INSERT ON 'bookings' FOR EACH ROW
BEGIN
    UPDATE bookings b
      SET booking_number = (SELECT CONCAT('BN-202105-000',COUNT(*) + 1) FROM bookings) 
      WHERE b.id = NEW.id;
END;

另一种解决方案是先将预订记录插入数据库,然后调用该generate_booking_id()函数来正确计算预订号码,然后将记录更新到数据库中:

 public function save_booking(Request $request){
            $booking = new Booking;
            $booking->booking_type              = $request->input('bookingType');
            $booking->booking_date              = $request->input('bookingDate');
            $booking->booking_time              = $request->input('bookingTime');
            $booking->booking_status            = $request->input('bookingStatus');
            $booking->save();

            $booking->booking_number            = generate_booking_id();
            $booking->save();
            
    }

推荐阅读