it-swarm-ko.tech

테이블 'watchdog'이 사용자 정의 모듈에서 LOCK TABLES로 잠기지 않았습니다.

테이블을 잠그는 데 필요한 모듈을 만들고 있습니다.

db_query('LOCK TABLES {eventi_list} READ');

$is_booked = _is_booked($uid, $nid);
if (! $is_booked) {
  $is_booked = _is_booked($uid, $nid, 'eventi_waiting_list');
}

if (! $is_booked) {
  $amount = _get_free_amount($nid);
  if ($amount > 0) {
    $insert = db_query("INSERT INTO {eventi_list} (uid, nid) VALUES($uid, $nid)");
  }
  else {
    $time = time();
    $insert = db_query("INSERT INTO {eventi_waiting_list} (uid, nid, created_at) VALUES($uid, $nid, $time)");
  }
  $update = db_query("UPDATE {content_type_event} SET field_event_places_amount_value = field_event_places_amount_value - 1 WHERE nid=$nid");
}
db_query('UNLOCK TABLES');

오류가 발생합니다 (4 개의 유사한 경고).

Warning: Table 'watchdog' was not locked with LOCK TABLES query:
INSERT INTO watchdog (uid, type, message, variables, severity, link, location, referer, hostname, timestamp) VALUES (19, 'php', '%message in %file on line %line.', 'a:4:{s:6:"%error";s:12:"user warning";s:8:"%message";s:139:"Table eventi_waits was not locked with LOCK TABLES query: SELECT count(nid) AS count FROM eventi_waits WHERE nid=201 AND uid=19";s:5:"%file";s:95:"D:\tools\xampp\htdocs\drupal\sites\bartenders.localhost.com\modules\\custom\eventi\eventi.module";s:5:"%line";i:115;}', 3, '', 'http://bartenders.localhost.com/bartender/book/201/%3Fdestination%3D/eventi/justin-knows', 'http://bartenders.localhost.com/eventi/justin-knows', '127.0.0.1', 1303900341) in D:\tools\xampp\htdocs\drupal\includes\database.mysqli.inc on line 135

이것으로 무엇을 할 수 있습니까? 데이터베이스보고를 끄십시오.

2
user1077

현재 코드에서는 작동하지 않습니다. 문제는보고가 아니라 잠금 구현입니다.

mysql 잠금 테이블 참조 에서

잠금이 필요한 세션은 단일 LOCK TABLES 문에서 필요한 모든 잠금을 획득해야합니다. 이렇게 얻은 잠금이 유지되는 동안 세션은 잠긴 테이블에만 액세스 할 수 있습니다.

잠금을 유지하는 동안 잠금 해제 된 테이블에 액세스하려고합니다.

내가 그것을 야생에서 사용했다고 말할 수는 없지만 대신 살펴보고 싶을 수도있는 Drupal 특정 잠금 메커니즘 이 있습니다.

3
Jeremy French

Jeremy French가 말한 것 외에도 :

  • 정말로 잠금을하고 싶다면 제공된 api 함수를 사용해야합니다 db_lock_table ()

  • 정말 % d 및 % s와 같은 자리 표시자를 사용하여 쿼리에 인수를 올바르게 전달해야합니다. 당신이하는 일은 불안정한 SQL 주입으로 이어질 수 있습니다. db_query () 문서를 다시 읽으십시오.

3
Berdir

코드가 잘못된 잠금을 사용하고 있습니다. 다음은 MySQL 5.0 참조 매뉴얼에보고 된 설명입니다.

읽기 [로컬] 잠금 :

잠금을 보유한 세션 은 테이블을 읽을 수 있지만 쓸 수는 없습니다 .

여러 세션이 테이블에 대한 READ 잠금을 동시에 획득 할 수 있습니다.

다른 세션은 명시 적으로 READ 잠금을 획득하지 않고도 테이블을 읽을 수 있습니다.

LOCAL 수정자를 사용하면 잠금이 유지되는 동안 다른 세션에서 충돌하지 않는 INSERT 문 (동시 삽입)을 실행할 수 있습니다. (섹션 7.7.3,“동시 삽입”참조) 그러나 잠금을 유지하는 동안 서버 외부의 프로세스를 사용하여 데이터베이스를 조작하려는 경우 READ LOCAL을 사용할 수 없습니다. InnoDB 테이블의 경우 READ LOCAL은 MySQL 5.0.13부터 READ와 동일합니다. (그 전에는 READ LOCAL이 기본적으로 아무 작업도하지 않습니다. 테이블을 전혀 잠그지 않으므로 InnoDB 테이블의 경우 일반 일관된 읽기 SELECT가 동일한 작업을 수행하고 잠금이 필요하지 않기 때문에 READ LOCAL을 사용하지 않습니다.)

코드가 읽기 잠금을 받고 있지만 테이블에 기록됩니다.

주 오류가 "event_list"가 쓰기 잠금 상태가 아니기 때문에 발생한다는 것을 알기 위해 watchdog()은 쓰기 잠금이되지 않은 테이블에 오류를 기록하려고합니다. Jeremy French가보고했듯이 코드는 필요한 모든 잠금을 획득해야합니다.

Bedir가 올바르게 사용하도록 제안한 함수 인 db_lock_table () 의 코드를 살펴보면 쓰기 잠금을 획득하고 있음을 알 수 있습니다.

function db_lock_table($table) {
  db_query('LOCK TABLES {' . db_escape_table($table) . '} WRITE');
}
2
kiamlaluno