get_uniqid 함수에 대하여 질문 드립니다.
본문
function get_uniqid()
{
global $g5;
sql_query(" LOCK TABLE {$g5['uniqid_table']} WRITE ");
while (1) {
// 년월일시분초에 100분의 1초 두자리를 추가함 (1/100 초 앞에 자리가 모자르면 0으로 채움)
$key = date('YmdHis', time()) . str_pad((int)(microtime()*100), 2, "0", STR_PAD_LEFT);
$result = sql_query(" insert into {$g5['uniqid_table']} set uq_id = '$key', uq_ip = '{$_SERVER['REMOTE_ADDR']}' ", false);
if ($result) break; // 쿼리가 정상이면 빠진다.
// insert 하지 못했으면 일정시간 쉰다음 다시 유일키를 만든다.
usleep(10000); // 100분의 1초를 쉰다
}
sql_query(" UNLOCK TABLES ");
return $key;
}
lib/common.lib.php 에서 2079 줄에서 부터 있는
유니크 아이디를 만드는 부분입니다.
주문번호등 을 만들어 질때 사용되고 있는 사용자함수(?)입니다.
이 부분을 보다가 의문 점이 들은 것이
sql_query(" LOCK TABLE {$g5['uniqid_table']} WRITE ");
1. 위 부분의 LOCK TABLE "AA" WRITE 입니다
이 부분이 사용되는 것이 무엇인지 궁금한데요
검색을 하며 보니 LOCK 을 걸어서
내가 아닌 다른 사용자가 순간적으로 DB에 쓰는 것을 막아서
uniqid 가 중복 되는걸 방지 하기 위해서가 맞는 건가요?
그런 목적으로 쓰이는 게 맞는 것인가요?
2.
$result = sql_query(" insert into {$g5['uniqid_table']} set uq_id = '$key', uq_ip = '{$_SERVER['REMOTE_ADDR']}' ", false);
if ($result) break; // 쿼리가 정상이면 빠진다.
위 부분에서
쿼리가 정상이면 빠지고 인서트 되지 않았을 경우 재시도를 하는데요
만에하나 저 부분이 중복일경우에 쿼리가 비정상이고 그러면 재시도를 하겠지요
LOCK TABLE 과는 관계 없이
중복일 경우에 쿼리가 비정상 출력 되나요?
대략 추측해보건데 디비 생성시 uq_id 부분에 '프라이머리 키'가 지정되어있기 때문에
자동으로 중복된 값은 '쓰기'가 안되는 건가요?
아니면 다른 부분에서도 쿼리가 실패할 수도 있어서 그런건가요?
(있다면 다른 실패요인도 알려주시면 감사하겠습니다..)
!-->
답변 1
1. 테이블 입력시 LOCK 을 걸어서 동일한 타이밍에 동일한 코드가 나오는걸 최대한 막고자 하는 로직으로 보여집니다 물론 innoDB 에서의 이야기겠구요..
2.
sql_query(
" UNLOCK TABLES "
); 여기를 타기 전 까지는 해당 테이블의 commit 은 정상적으로 타지 않아서 데이터 저장은 되지 않겠죠
참고자료로 isolation level 관련 링크 남겨봅니다.
https://dev.mysql.com/doc/refman/5.6/en/dynindex-isolevel.html