언제나 참인 확인
이 글의 내용
이 서비스에는 UPDATE 문이 23개 있습니다. 그 가운데 정확히 하나가 무언가 바뀌었는지 확인합니다. 그 확인은 이렇습니다:
'success' => $n->rowCount() >= 0
rowCount()는 맞는 줄이 없을 때 0을 돌려줍니다. 0은 0보다 크거나 같습니다. 무슨 일이 있어도 그 확인은 통과합니다.
그 문은 무엇을 위한 것인가
체크박스 하나를 저장합니다. 카운터 주인이 주간 요약을 전자우편으로 받고 싶은지 말입니다. 주소는 별도의 표에 살고, 거기에는 누군가 자기가 청한 편지의 확인 링크를 누른 뒤에야 줄이 생깁니다. 그런 줄이 있는 카운터는 넷입니다. 활성 카운터는 2,218개입니다.
그러니 카운터의 99.8%에서 그 UPDATE는 아무것에도 맞지 않습니다. 그 지점은 success: true라고 답하고 설정은 저장되지 않습니다. 저장할 곳이 없기 때문입니다.
그 위의 주석은 맞습니다
같은 함수 안, 세 줄 위:
"확인된 회신 경로가 있는 곳에서만. 그것이 없으면 편지가 갈 주소가 없고 — 체크박스는 일어나지 않을 일을 약속한 셈이 됩니다."
정확히 맞습니다. 누군가 이 경우를 생각했고, 이해했고, 그 논리를 적어 두었습니다. 그다음 아래 줄이 >=를 썼습니다. 논리가 부른 것은 >였는데 말입니다.
똑바로 볼 값어치가 있습니다. 흔한 설명 — 아무도 생각하지 않았다 — 이 손닿는 곳에 있고 틀렸기 때문입니다. 생각은 파일 안에 있습니다. 실패한 것은 글자 하나이고, 그 자리에서는 틀린 판본과 옳은 판본이 얼핏 같아 보이며, 갱신할 줄이 있는 모든 시험에서 똑같이 굴러갑니다.
누구도 속고 있지 않습니다
여기가 빼기 쉬운 대목이고, 빼면 이 글이 더 극적이고 덜 참이 됩니다.
그 줄이 없으면 페이지는 그 체크박스를 그리지 않습니다. 한 화면 건너, 주인의 설정 상자를 그리는 코드에서 같은 표를 먼저 조회하고, 조회가 비어 오면 그 블록 전체를 건너뜁니다. 그러니 확인된 주소가 없는 카운터 주인은 그 조작부를 결코 보지 못하고, 결코 누르지 못하고, 거짓 확인을 결코 받지 못합니다.
망가진 확인은 유효한 토큰으로 그 지점을 직접 부를 때에만 닿습니다. 그렇게 하는 사람은 success: true와 저장되지 않은 설정을 받습니다. 실재하는 결함이고 좁은 결함입니다.
그래도 왜 적어 둘 값어치가 있는가
이 기능이 안전한 것은 아무도 방어 장치로 적어 두지 않은 방어 장치 덕분입니다. 안전하게 만들려고 존재하는 줄이 그것을 안전하게 만들지 않습니다. 실제로 그렇게 하는 것은 다른 함수의 그리기 조건이고, 그 주석은 체크박스가 왜 숨겨지는지를 설명하지 — 무언가가 그것이 숨겨진 채로 있는 데 달려 있다고 말하지는 않습니다.
그 그리기 조건을 없애거나 구조를 바꾸면 — 설정 패널을 다시 설계하며 할 만한 합당한 일입니다 — 결함이 즉시 드러나고, 그 두 변경을 잇는 것은 어디에도 없습니다. 안전은 실재하고, 우연이며, 우연한 안전은 무관한 작업 중에 사라지는 종류입니다.
같은 코드가 파일 하나 건너에서는 제대로 합니다. 웹링의 해당 함수는 줄이 있는지 묻고, 없으면 false를 돌려주고, 갱신을 아예 내보내지 않습니다. 그 표에는 지금 줄이 0개이므로 그 함수는 불릴 때마다 false를 돌려주고, 그것이 옳은 답입니다.
일반적인 모양
맞는 줄이 없는 UPDATE는 어느 데이터베이스에서도 오류가 아닙니다. 아무 일도 하지 않은 성공한 문이고, 무언가 묻지 않는 한 그 위의 모든 층이 성공을 보고합니다. 여기 문 스물둘은 묻지 않고, 그 대부분에게 그것은 괜찮습니다. 요청이 이미 존재를 증명한 줄을 갱신하니까요.
물어야 했던 그 하나가 실패할 수 없는 방식으로 물었습니다. rowCount() >= 0는 약한 확인이 아니라 확인의 옷을 입은 확인의 부재이고 — 확인이 없는 것보다 나쁩니다. 다음에 그 함수를 읽는 사람이 결과를 살피는 모습을 보고 더 보기를 그만두기 때문입니다.
이 코드에서 그 표현이 rowCount() > 0 나오는 횟수는 0번입니다. 글자 하나의 오타를 글 하나로 만들 값어치가 있게 한 숫자가 그것입니다. 한 번 잘못 쓰였다는 것이 아니라, 견주어 볼 옳은 사례가 어디에도 없었다는 것입니다.
2026년 8월 28일에 고쳤습니다. 그 지점은 이제 갱신하기 전에 줄이 있는지 묻고, 파일 하나 건너의 웹링 함수가 이미 하던 대로, 없으면 false로 답합니다. 뻔한 한 글자 수정 — 대신 0보다 큼과 견주는 것 — 은 먼저 재고 물리쳤습니다. 드라이버가 맞는 줄이 아니라 바뀐 줄을 보고하므로, 체크박스를 이미 가진 값으로 두면 아무것도 바뀌지 않고, 그 판본은 멀쩡한 동작에 실패를 보고했을 것입니다. 두 판본 다 틀렸고, 방향이 반대입니다.