Удалить запрос на экспресс с помощью формы не работает

Механизм MyISAM MySQL может это сделать. См. Их руководство в разделе Использование AUTO_INCREMENT :

Для таблиц MyISAM вы можете указать AUTO_INCREMENT на вторичном столбце в индексе с несколькими столбцами. В этом случае генерируемое значение для столбца AUTO_INCREMENT вычисляется как MAX (auto_increment_column) + 1 WHERE prefix = given-prefix. Это полезно, когда вы хотите поместить данные в упорядоченные группы.

blockquote>

Документы продолжаются после этого параграфа, демонстрируя пример.

Механизм InnoDB в MySQL не поддерживайте эту функцию, что является неудачным, потому что лучше использовать InnoDB практически во всех случаях.

Вы не можете эмулировать это поведение с помощью триггеров (или любых операторов SQL, ограниченных областью транзакций) без блокировки таблиц в INSERT. Рассмотрим эту последовательность действий:

  1. Mario начинает транзакцию и вставляет новую строку для пользователя 4.
  2. Билл начинает транзакцию и вставляет новую строку для пользователя 4.
  3. Сеанс Марио запускает триггер для вычисления MAX (id) +1 для пользователя 4. Вы получаете 3.
  4. В сеансе Билла срабатывает триггер для вычисления MAX (id). Я получаю 3.
  5. Заседание Билла заканчивает его INSERT и совершает.
  6. Сеанс Марио пытается завершить свой INSERT, но теперь строка с (userid = 4, id = 3) существует, поэтому Марио получает конфликт с первичным ключом.

В общем, вы не можете контролировать порядок выполнения этих шагов без какой-либо синхронизации.

Решения для это либо:

  • Получите эксклюзивную блокировку таблицы. Перед тем, как попробовать INSERT, заблокируйте таблицу. Это необходимо, чтобы предотвратить одновременные ВСТАВКИ от создания условия гонки , как в приведенном выше примере. Необходимо заблокировать всю таблицу, так как вы пытаетесь ограничить INSERT, нет конкретной строки для блокировки (если вы пытаетесь управлять доступом к данной строке с помощью UPDATE, вы можете заблокировать только определенную строку). Но блокировка таблицы приводит к тому, что доступ к таблице становится последовательным, что ограничивает вашу пропускную способность.
  • Сделайте это за пределами транзакции. Создайте идентификационный номер таким образом, чтобы он не скрывался от двух параллельных транзакций. Кстати, это то, что делает AUTO_INCREMENT. Два параллельных сеанса будут получать уникальное значение id независимо от порядка выполнения или порядка фиксации. Но отслеживание последнего сгенерированного идентификатора для каждого пользователя требует доступа к базе данных или дублированного хранилища данных. Например, ключ memcached для каждого пользователя, который может быть инкрементирован атомарно .

Относительно легко убедиться, что вставки получают значения unique , Но трудно гарантировать, что они получат последовательные порядковые значения. Также рассмотрите:

  • Что произойдет, если вы вСТАВИТЕСЬ в транзакции, а затем откат? Вы указали значение 3 в этой транзакции, а затем я выделил значение 4, поэтому, если вы откат и я зафиксирую, теперь есть пробел.
  • Что произойдет, если INSERT завершится с ошибкой из-за других ограничений на таблица (например, другой столбец NOT NULL)? Вы также можете получить пробелы.
  • Если вы когда-либо удаляете строку, вам нужно перенумеровать все следующие строки для одного и того же идентификатора пользователя? Что это делает для ваших записей memcached, если вы используете это решение?

0
задан Mikev 28 February 2019 в 09:06
поделиться

2 ответа

Если вы отметите Документы MDN :

метод HTTP-метод, который браузер использует для отправки формы. Возможные значения:

post : Соответствует методу HTTP POST; Данные формы включаются в тело формы и отправляются на сервер.

get : соответствует методу HTTP GET; данные формы добавляются к URI атрибута действия с символом «?» в качестве разделителя, и в результате.

Если вы хотите отправить удаление, прослушайте событие submit в форме, позвоните event.preventDefault(), чтобы остановить действие по умолчанию, и сделайте свой собственный запрос к бэкэнду, что более типично. «современный» способ сделать это в любом случае, так как это не приводит к обновлению страницы.

Также ваш маршрут не будет поврежден без чего-либо в части :id.

Один из способов сделать это заключается в следующем:

Дайте вашей форме класс или найдите способ ссылаться на него

<form action="/api" method="post" id="test-form">
    <input type="number" name="id" placeholder="delete" /><br/>
</form>

В вашем JavaScript, найти способ ссылки на форму и запретить ее отправку:

const form = document.getElementById('test-form');
form.addEventListener('submit', async event => {
    event.preventDefault();     // This prevents the form from submitting using POST

    const idInput = form.querySelector('input[name="id"]');
    const id = idInput.value;

    const res = await fetch(`https://apiurl.com/api/${id}`, {
      method: 'DELETE',
    });
    const json = await res.json();

    console.log(json);
});
0
ответ дан Dominic 28 February 2019 в 09:06
поделиться

Поскольку форма не поддерживает метод удаления, вы можете запретить отправку формы автоматически и отправить запрос вручную, используя либо API выборки, либо jquery xhr:

 <form action="/api" method="" id="deleteApi">
    <input type="number" name="id" placeholder="delete" /><br/>
    <input type="submit" value="Submit">
 </form>

js код:

[ 111]
0
ответ дан Kossi D. T. S. 28 February 2019 в 09:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: