我正在建立一個酒店式預訂系統,我正在放鬆方式。我在預訂時刻卡住了什麼時候添加預訂,我擔心來臨的情況。預防酒店預訂系統中的競爭條件和鎖定表PHP/MySQL
我的流程非常簡單,它允許多個用戶通過同一個房間的預定過程,直到其中一個人按下預定按鈕之前的其他人。預訂信息保存在會話中,直到有人到達最後一步並按「書」,永遠不會存儲在數據庫中。在每個步驟中,系統檢查房間是否可用,如果沒有,則提供錯誤頁面。現在
問題是防止競爭條件相結合,最後一個強制性的檢查,如果仍然有足夠的房間了:
當用戶在最後一步時,他/她選擇的付款方式,按書按鈕。檢查是否選擇的付款方式是確定的(表格數據沒有被修改)後,它重定向到保留控制器,其中:
預約控制器
<?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_p大米,房間數量等),它有一個外鍵和#__房間和一個#__預訂
我關心什麼?
1 - 我在最後的可用性檢查過程中使用其他表,而不是兩個鎖定,並給我錯誤。
2 - 當第二個用戶的執行到達表鎖定點時,它是否等到它們獲得空閒或是否會引發錯誤/異常?我可以捕獲異常並將用戶重定向到錯誤頁面,但是加密表表示並不意味着保留位置,保存信息時可能會發生任何問題。
我希望我的工作流程正常,請告訴我,如果我很好,或者我應該改進我的代碼。
感謝
編輯:
要被提及的經營思路是像Expedia的,即,預訂,等在那裏你被允許每個預訂選擇更多的房間類型和單位。事實上,我的房間的桌子不是針對特定/真實的房間,而是爲了房間類型,如果沒有預訂,每天都有固定數量的房間。
如果每個房間在#__房間表中有一排並且每個預訂的房間都有預訂,我可以接受您的答案,但是,你知道,那不是一個好選擇。我想讓用戶預訂多個房間是相同的預訂,即使因爲我管理的房間類型不僅僅是特定房間的單位數量。 –
@MarcoC如果用戶預訂了多個房間,那麼請讓每個房間預訂其自己的記錄。它將在一個單獨的表中(不是'預訂'),並且所有這些記錄都有相同的'reservationID' - 一個外鍵。在這種情況下,'UNIQUE'索引仍然是'roomID,date'。由於你有其他的住宿(例如公寓),可能'roomID'不是最好的字段名稱,但是概念是相同的:對於特定空間被保留的唯一標識符 – BeetleJuice
'保留特定空間的唯一標識符' - 最短但最準確的答案 –