본문으로 건너뛰기

DB 데드락 자동 복구 및 발송/장바구니 교착 완화

PHP 7 · GODO25
변경 파일 수: 3개
변경 파일 목록
3
변경 파일 코드
추가삭제
Component/Cart/Cart.php+4
변경 전Cart.php
return false;
}
 
 
 
 
 
$arrBind = [];
foreach ($getData as $cartSno) {
// 장바구니 삭제 전 쿠폰 장바구니사용 상태 되돌리기
 
변경 후Cart.php
return false;
}
 
// [데드락 회피] sno IN 다건 삭제 시 PK 잠금 순서를 오름차순으로 통일
// 삭제 대상 집합은 동일하며(동작 불변), 동시 트랜잭션 간 PK 획득 순서만 일치시켜 교착 순환을 제거
sort($getData, SORT_NUMERIC);
 
$arrBind = [];
foreach ($getData as $cartSno) {
// 장바구니 삭제 전 쿠폰 장바구니사용 상태 되돌리기
 
Component/Mail/MailLog.php+21
변경 전MailLog.php
protected $arrWhere;
/** @var int es_mailLog sno */
private $_sno;
 
 
/** @var SimpleStorage */
private $requestStorage;
$arrBind = $this->db->get_binding(DBTableField::tableMailSendList(), $bindArray, 'insert');
$this->db->set_insert_db(DB_MAIL_SEND_LIST, $arrBind['param'], $arrBind['bind'], 'y');
 
 
unset($arrData);
}
*/
public function updateSendList($email)
{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
$this->db->bind_param_push($arrBind, 's', $this->_sno);
$this->db->bind_param_push($arrBind, 's', $email);
$this->db->set_update_db(DB_MAIL_SEND_LIST, 'acceptCheckFl = \'y\'', 'mailLogSno = ? AND receiverEmail = ? AND acceptCheckFl = \'n\' LIMIT 1', $arrBind);
 
변경 후MailLog.php
protected $arrWhere;
/** @var int es_mailLog sno */
private $_sno;
/** @var int|null 직전 insertMailSendList 로 INSERT 한 es_mailSendList 의 PK(sno). updateSendList PK 단건 갱신용 */
private $sendListSno = null;
/** @var SimpleStorage */
private $requestStorage;
$arrBind = $this->db->get_binding(DBTableField::tableMailSendList(), $bindArray, 'insert');
$this->db->set_insert_db(DB_MAIL_SEND_LIST, $arrBind['param'], $arrBind['bind'], 'y');
// 방금 INSERT 한 발송내역 PK 를 보관 → updateSendList 에서 PK 단건 갱신(데드락 회피)에 사용
$this->sendListSno = (int) $this->db->insert_id();
unset($arrData);
}
*/
public function updateSendList($email)
{
// [데드락 회피] 직전 insertMailSendList 로 확보한 PK(sno)가 있으면 PK 단건 UPDATE
// 보조인덱스(ix_es_mailSendList_05) 스캔을 제거해 잠금 순서를 PRIMARY 기준으로 통일
// acceptCheckFl='n' 가드를 유지해 멱등성을 보장(기존 동작과 동일하게 미접수 건만 갱신)
// 사용 후 즉시 초기화하여, INSERT 가 선행되지 않은 호출은 아래 기존 로직으로 처리
if (!empty($this->sendListSno)) {
$sendListSno = $this->sendListSno;
$this->sendListSno = null;
$arrBind = [];
$this->db->bind_param_push($arrBind, 'i', $sendListSno);
$this->db->set_update_db(DB_MAIL_SEND_LIST, 'acceptCheckFl = \'y\'', 'sno = ? AND acceptCheckFl = \'n\'', $arrBind);
return;
}
// (fallback) PK 미확보 호출 경로 — 기존 동작 100% 유지
$arrBind = [];
$this->db->bind_param_push($arrBind, 's', $this->_sno);
$this->db->bind_param_push($arrBind, 's', $email);
$this->db->set_update_db(DB_MAIL_SEND_LIST, 'acceptCheckFl = \'y\'', 'mailLogSno = ? AND receiverEmail = ? AND acceptCheckFl = \'n\' LIMIT 1', $arrBind);
 
Controller/Front/Order/CartPsController.php+15-5
변경 전CartPsController.php
}
// 처리별 이동 경로
if (gd_isset($postValue['cartMode']) == 'd') {
$goodsList = implode(',', $addedGoods);
$goodsListQuote = implode(',', $addedGoodsQuote);
//장바구니에서 보이지 않도록 조치 시작
$this->db = \App::load('DB');
$where = 'sno IN (\''.str_replace(',', '\',\'', $goodsList.'\')');
$arrUpdate['directCart'] = 'y';
$arrBind = $this->db->get_binding(DBTableField::tableCart(), $arrUpdate, 'update', array_keys($arrUpdate));
$this->db->set_update_db(DB_CART, $arrBind['param'], $where, $arrBind['bind']);
 
 
 
 
 
 
 
 
 
 
 
//장바구니에서 보이지 않도록 조치 종료
 
$goodsListQuote = '['.$goodsListQuote.']';
 
변경 후CartPsController.php
}
// 처리별 이동 경로
if (gd_isset($postValue['cartMode']) == 'd') {
 
$goodsListQuote = implode(',', $addedGoodsQuote);
//장바구니에서 보이지 않도록 조치 시작
$this->db = \App::load('DB');
// [데드락 회피] UPDATE WHERE 의 sno IN 잠금 순서만 오름차순 통일(대상 행 동일)
// URL(cartIdx) 노출 순서에는 영향을 주지 않도록 정렬 복사본을 별도 생성
$sortedAddedGoods = $addedGoods;
sort($sortedAddedGoods, SORT_NUMERIC);
 
if (!empty($sortedAddedGoods)) {
$arrUpdate['directCart'] = 'y';
$arrBind = $this->db->get_binding(DBTableField::tableCart(), $arrUpdate, 'update', array_keys($arrUpdate));
// sno IN 값은 바인딩으로 처리(SQL 인젝션 방지)
$where = 'sno IN (' . implode(', ', array_fill(0, count($sortedAddedGoods), '?')) . ')';
foreach ($sortedAddedGoods as $sno) {
$this->db->bind_param_push($arrBind['bind'], 'i', $sno);
}
$this->db->set_update_db(DB_CART, $arrBind['param'], $where, $arrBind['bind']);
}
//장바구니에서 보이지 않도록 조치 종료
 
$goodsListQuote = '['.$goodsListQuote.']';