我正在建立一个酒店式的预订系统,但我迷路了。我在添加预订的确切预订时刻卡住了,我担心即将到来的情况。
我的流程非常简单,它允许多个用户完成同一个房间的预订过程,直到其中一个用户先于其他用户按下预订按钮。预订信息保留在会话中,并且在有人到达最后一步并按“预订”之前永远不会存储在数据库中。在每一步中,系统都会检查房间是否可用,如果不可用,则会给出错误页面。
现在的问题是防止竞争条件与最后一个强制检查是否仍有足够的房间相结合:
当用户在最后一步时,他/她选择付款方式并按下预订按钮。在检查所选付款选项是否正常(表单数据未更改)后,它会重定向到预订控制器,其中:
预订控制器
<?php
ReservationController extends JControllerLegacy{
public function placeReservation(){
//Do some checks to prevent direct access, booking existence and user completed all steps
$reservatioModel = $this ->getModel('Reservation')
if(!$reservationModel->placeReservation()){
//set errors and redirect to error page
return false;
}
//booking had been placed, passes the data to payment plugin
}
?>
和
预订型号:
<?php
ReservationModel extends JModelLegacy{
public function placeReservation(){
//Get all variables and objects
//Lock the tables to prevent any insert while the last check
$db ->lockTable(#__bookings);
$db ->lockTable(#__booking_room);
//Perform the last mandatory check with tables locked to prevent read the table right one moment before another transaction insert the booking and allowing overbooking. THIS CHECK MUST BE 100% SURE NO ONE ELSE IS MANIPULATING/READING THE TABLE
if(!$this ->checkRoomsAvailability($data))
return false;
try{
$db ->transactionStart();
//Add the reservation in the booking table
if(!$this ->_saveBooking()){
$db ->rollBack();
return false;
}
//Add the room/s to the middle table #__booking_room
if(!$this -> _saveRooms())
$db ->rollBack();
return false;
}
$db ->transactionCommit();
}catch(Exception $e){
$db ->rollBack();
$this ->setError('We were not able to complete your reservation.');
return false;
}
$db ->unlockTables();
}
?>
上面提到的表是 InnoDB,#__bookings 保存预订,#__booking_room 保存所选房间的信息(如 avg_price、房间数等),它有一个外键到 #__rooms 和一个到 #__bookings
我在担心什么?
1 - 我在最后一次可用性检查期间使用了其他表,而不是两个锁定的表,并且给了我错误。
2 - 当第二个用户的执行到达表锁定点时,它是等到他们获得空闲还是引发错误/异常?我可以捕获异常并将用户重定向到错误页面,但小盒表并不意味着已放置预订,在保存信息时可能会出现任何问题。
我希望我的工作流程没问题,请让我知道我是否可以继续,或者我应该改进我的代码。
谢谢
编辑:
值得一提的是,商业理念就像 Expedia、预订等,您可以在每次预订时选择更多的房间类型和单位。事实上,我的房间桌子不是针对特定/真实房间的,而是针对房间类型,如果尚未预订,则每天都有固定数量的可用单元。