get_uniqid 함수에 대하여 질문 드립니다. 채택완료
</p><p>function get_uniqid()</p><p>{</p><p> global $g5;</p><p> sql_query(" LOCK TABLE {$g5['uniqid_table']} WRITE ");</p><p> while (1) {</p><p> // 년월일시분초에 100분의 1초 두자리를 추가함 (1/100 초 앞에 자리가 모자르면 0으로 채움)</p><p> $key = date('YmdHis', time()) . str_pad((int)(microtime()*100), 2, "0", STR_PAD_LEFT);</p><p> $result = sql_query(" insert into {$g5['uniqid_table']} set uq_id = '$key', uq_ip = '{$_SERVER['REMOTE_ADDR']}' ", false);</p><p> if ($result) break; // 쿼리가 정상이면 빠진다.</p><p> // insert 하지 못했으면 일정시간 쉰다음 다시 유일키를 만든다.</p><p> usleep(10000); // 100분의 1초를 쉰다</p><p> }</p><p> sql_query(" UNLOCK TABLES ");</p><p> return $key;</p><p>}</p><p>
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">https://dev.mysql.com/doc/refman/5.6/en/dynindex-isolevel.html
댓글을 작성하려면 로그인이 필요합니다.
답변을 작성하려면 로그인이 필요합니다.
로그인