Что-то "фанковое" произошло три дня назад - и нет, я пока не смог понять, что "фанково" означает. Но одним из симптомов является то, что записи, которые я добавляю или обновляю, больше не «берутся». Причина, по которой я начинаю с удаленной таблицы, заключается в том, что это место, где это происходит чаще всего, и его легче всего дублировать.
У меня открыто одно окно, в котором запущено веб-приложение, и еще одно окно открывается с запуском phpMyAdmin, а третье окно открывается с запуском приложения, которое отслеживает error_log, куда я сбрасываю выходные данные отладки.
- В первом окне я Я запускаю приложение, в котором я помечаю посетителя для удаления, нажимаю «Отправить», а затем проверяю, исчез ли он. Это трехэтапный процесс: 1) перейдите к списку активных посетителей и выберите запись, 2) вы заходите в запись посетителя, где нажимаете "Удалить", затем нажмите "Отправить" и 3) возвращаетесь к списку активных посетителей, чтобы увидеть это. записи больше нет в списке.
- Во втором окне я запускаю команду SQL для проверки таблиц. Ниже я включу команды SQL.
- В третьем окне смотрю ошибки.
Код: Выделить всё
SELECT
COUNT(*) AS isGone,
R.tstamp_add AS WhenRemoved
FROM removed R
WHERE visitor_id = :id;
SELECT *
FROM removed R
ORDER BY R.rowid DESC
LIMIT 5;
SELECT V.rowid, V.visitor_name, V.tstamp_del
FROM visitors V
ORDER BY V.tstamp_del DESC
LIMIT 5;
(Основные данные выделены жирным шрифтом):< /p>
Код: Выделить всё
isGone WhenRemoved
1 **2024-07-16 23:24:04**
Код: Выделить всё
rowid visitor_id tstamp_add
**1471 213 2024-07-16 23:24:04**
1463 210 2024-07-16 18:06:46
1460 827 2024-07-16 17:33:34
1446 676 2024-07-16 03:24:05
1445 677 2024-07-16 03:23:50
Код: Выделить всё
rowid visitor_name tstamp_del
**213 Daniel Berry 2024-07-16 23:24:04 **
212 Daniel Berry 2024-07-16 19:09:46
211 Daniel Berry 2024-07-16 18:36:58
210 Daniel Berry 2024-07-16 18:06:46
827 Josie Wales 2024-07-16 17:33:34
Код: Выделить всё
[17-Jul-2024 03:24:04 UTC] 2024-07-17 03:24:04.905109
MSG: rval after archiving:
{"del":1,"remove":"**1471**","checking":"**2024-07-16 23:24:04**"}
[17-Jul-2024 03:24:04 UTC] 2024-07-17 03:24:04.901710
MSG: doing archive vid:[213]
[*]Запись было помечено как удаленное. В первом сообщении журнала "del":1 показывает, что после процесса удаления была изменена одна строка в "удаленной" таблице, как указано в первом выводе SQL.
[*]"Удалено" " таблица имеет следующий ключ с правильными visitor_id и датой.
[*]В таблице "посетители" указана правильная дата в поле tstamp_del.
Я уверен, некоторые проницательные люди заметят, что поле auto_increment для новой записи (1471) на 8 больше, чем для следующей записи (1463), что на 3 больше, чем для следующей записи (1460). ), с еще одним большим пропуском перед следующим (1446).
Происходит следующее: после того, как я возвращаюсь к списку посетителей в приложении, tstamp_del в записи посетителя возвращается к NULL , а запись с идентификатором rowid 1471 просто исчезает из таблицы.
Об ошибках не сообщается, нет.
У меня есть 6 тестовых записей, которые я пробую чтобы разобраться: 827, 210, 211, 212, 213 и 214.
Чтобы попытаться выяснить, в чем заключается «проблема», я добавляю дополнительный код отладки. А когда у меня опечатка или еще какая подобная глупость и программа вылетает, то удаление "залипает". Вот почему вы можете видеть 827, 210 и 213. На самом деле вы видите только 213, потому что этот снимок находится в середине обработки — как только я обновлю страницу, он исчезнет.
Такое ощущение, что PDO выполняет откат, но у меня нулевой код транзакции. На самом деле, я потратил пару часов, пытаясь выяснить, как гарантировать, что PHP/PDO/MySQL запрещено выполнять транзакции, но безуспешно.
Просто для смеха и ухмылки. , вот метод, который добавляет элемент в удаленную таблицу:
Код: Выделить всё
public function setRemoved($visitor_id)
{
$sql = 'INSERT INTO removed (visitor_id) VALUES (:v)';
$data = [ 'v' => $visitor_id ];
$sqlmsg = "Setting removed for prospect [$visitor_id]:" .
' for: ' . __METHOD__ . '::' . __LINE__ .
" // SQL: [$sql] // DATA:[" . $this->const->printr($data) . "]";
$this->log->log(logTRACE, __METHOD__, __LINE__, $sqlmsg);
try {
if ($stmt = $this->db->prepare($sql))
{
$stmt->execute($data);
return($this->db->lastInsertId());
}
else
{ throw new Exception('prepare == false', __LINE__); }
}
catch (PDOException $e)
{
$this->log->logsqlerr(__METHOD__, __LINE__,
$sqlmsg, $e);
return(false);
}
catch (Exception $e)
{
$this->log->logsqlerr(__METHOD__, __LINE__,
$sqlmsg, $e);
return(false);
}
}
Для полноты, вот что устанавливает запись посетителя:
Код: Выделить всё
public function delVisitor($visitor_id = NULL)
{
if (empty($visitor_id)) { return(0); }
$sql = 'UPDATE visitors SET tstamp_del = :t WHERE rowid = :v';
$data = [
't' => $this->const->fixDateTime('now', 'Y-m-d H:i:s'),
'v' => $visitor_id
];
$sqlmsg = 'Deleting prospect record:' .
' for: ' . __METHOD__ . ' at: ' . __LINE__ .
" // SQL: [$sql] // DATA:[" . $this->const->printr($data) . "]";
$this->log->log(logTRACE, __METHOD__, __LINE__, $sqlmsg);
try {
if ($stmt = $this->db->prepare($sql))
{
$stmt->execute($data);
return(true);
}
else
{ throw new Exception('prepare == false', __LINE__); }
}
catch (PDOException $e)
{
$this->log->logsqlerr(__METHOD__, __LINE__,
$sqlmsg, $e);
return(false);
}
catch (Exception $e)
{
$this->log->logsqlerr(__METHOD__, __LINE__,
$sqlmsg, $e);
return(false);
}
}
Я не против исследования; Я не против читать что-то — я действительно хочу понимать и учиться. Но я никогда не видел подобных вещей, за исключением транзакций, которые были отменены. Я старался НЕ использовать транзакции в этом приложении. Они слишком просто нужны.
Несколько подробностей: MariaDB 11.4.x, PHP 8.x.
Пожалуйста: есть ли у кого-нибудь еще видел такое? В чем была проблема?
Подробнее здесь: https://stackoverflow.com/questions/787 ... ut-changes