Задать вопрос
  • Как объединить запросы в транзакцию?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Поскольку быстрым поиском готовый ответ на Тостере не находится, стоит написать канонический.

    Сначала общая информация:

    Транзакция служит для обеспечения принципа "всё или ничего", гарантируя, что либо все запросы выполнились без ошибок, либо, если в каком-то из запросов произошла ошибка, то все предыдущие будут отменены, как будто их и не было вовсе. Из чего можно сделать следующие выводы:
    • транзакция не нужна для любого количества запросов на выборку данных, поскольку там нечего откатывать
    • транзакция не нужна для одного запроса на изменение данных (вставка, обновление, удаление) - такой запрос представляет из себя мини-транзакцию, которая сама автоматом откатывается при ошибке
    • не следует путать транзакции с блокировками. Хотя при определённых параметрах транзакции могут выполнять и блокировку, в общем случае это два разных механизма, которые могут выполняться как вместе, так и по отдельности. По умолчанию транзакция НЕ обеспечивает блокировку таблиц, участвующих в запросе


    Самым простым вариантом будет заключить запросы между вызовами beginTransaction() и commit(), как показано например в документации к последнему.
    $db->beginTransaction();
    $db->prepare("UPDATE `tab1` SET `col` = ?")->execute($data1);
    $db->prepare("UPDATE `tab2` SET  `col` = ?")->execute($data2);
    $db->prepare("UPDATE `tab3` SET  `col` = ?")->execute($data3);
    $db->commit();

    Для современных версий РНР этого должно быть достаточно: начиная с РНР 8.0 ошибочный запрос по умолчанию выбрасывает исключение. Не пойманное исключение прерывает выполнение РНР скрипта. При прерывании выполнения скрипта РНР закрывает соединение с Mysql, а при закрытии соединения Mysql откатывает все открытые в нём транзакции.

    Соответственно, при ошибке в любом из запросов транзакция автоматически откатится. А при успешном выполнении всех запросов транзакция, соответственно, закоммитится.

    В редких случаях, когда после отката транзакции предполагается дальнейшее выполнение кода, можно заключить код транзакции в try-catch и откатить её вручную.

    Важно помнить некоторые особенности.
    • в mysql не все движки таблиц поддерживают транзакции. впрочем ,учитывая что innodb является движком по умолчанию уже лет 20, это вряд ли будет проблемой
    • запросы на изменение страктуры таблиц автоматически коммитят стартовавшую транзакцию, то есть их следует избегать. Кажется, в новых версиях какие-то уже не коммитят, но я предпочитаю избегать всё равно.


    Также желательно помнить, что в любом более-менее сложном коде очень быстро появляются вложенные транзакции, а PDO при попытке стартовать транзакцию при уже открытой, выбросит исключение, что, соответственно, приведёт к откату родительской (и это гораздо лучше поведения MySQL по умолчанию, которая автоматически коммитит старую). И имеет смысл накидать простой кодик, который считает вложенные транзакции, и не стартует, если уже был старт, а при коммите вычитает вложенность, а реально коммитит только если вложенности не осталось. Что-то вроде кода из комментариев к beginTransaction(), подравняв его напильником
    class \MyPDO extends \PDO
    {
        protected $transactionCounter = 0;
    
        public function beginTransaction()
        {
            if($this->transactionCounter++ === 0) {
                return parent::beginTransaction();
            }
        }
        public function commit()
        {
            $this->transactionCounter--;
            if($this->transactionCounter === 0) {
                return parent::commit();
            }
        }
        public function rollback()
        {
            $this->transactionCounter = 0;
            return parent::rollback();
        }
    }

    разместив его либо прямо в PDO, либо в своем враппере.
    Ответ написан
    3 комментария
  • По какому принципу работает алгоритм с массивом очереди?

    Вот вам готовая простейшая очередь в виде объекта без всяких переборов:

    class Queue {
      constructor() {
        this.items = {};
        this.front = 0;
        this.rear = 0;
      }
      enqueue(item) {
        this.items[this.rear] = item;
        this.rear++;
      }
      dequeue() {
        const item = this.items[this.front];
        delete this.items[this.front];
        this.front++;
        return item;
      }
      peek() {
        return this.items[this.front];
      }
      get size() {
        return this.rear - this.front;
      }
      isEmpty() {
        return this.rear == 0;
      }
    }
    const queue = new Queue();
    queue.enqueue(1);
    queue.enqueue(2);
    queue.enqueue(3);
    queue.enqueue(4);
    queue.enqueue(5);
    
    console.log("Объект очереди: ", queue);
    
    const removed_element = queue.dequeue();
    console.log("Обработанный (удаленный) элемент: ", removed_element);
    
    console.log("Объект очереди:", queue);
    
    const top_element = queue.peek();
    console.log("Текущий элемент очереди для обработки (без удаления): ", top_element);
    
    const queue_length = queue.size;
    console.log("Размер очереди: ", queue_length);
    Ответ написан
    Комментировать
  • Как обезопасить программу С# от взлома?

    CityCat4
    @CityCat4 Куратор тега Информационная безопасность
    Дома с переломом ноги
    Что за каша? Что такого ценного в "других программах" и от чего их надо защищать? Сама программа обычно является обьектом защиты только если это игра - то есть работа программы самой по себе (среди не-игр это редко). Обычно не-игра защищается тогда, когда она производит что-то ценное.

    Вопрос - что ценного в ваших программах? Кому они нужны, кто будет их ломать?
    Ответ написан
    Комментировать
  • Как проверять подлинность данных, отправляемых клиентом в базу данных?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Способ только один - все действия делаются исключительно на сервере. От клиента только приходят команды на операции с токенами.
    Ответ написан
    3 комментария
  • Как проверять подлинность данных, отправляемых клиентом в базу данных?

    все расчёты, связанные с важными переменными происходят со стороны клиента

    Все расчеты связанные с важными переменными должны происходить на стороне сервера
    668c1b7a7dc2f372259442.png
    Ответ написан
    1 комментарий
  • Как проверять подлинность данных, отправляемых клиентом в базу данных?

    ThunderCat
    @ThunderCat Куратор тега Веб-разработка
    {PHP, MySql, HTML, JS, CSS} developer
    В этом куске кода критическая переменная это tokens. При нажатии на кнопку start со стороны клиента у пользователя отнимается один токен и кол-во общих токенов отправляется в бд
    Не надо тупить. Раз токен это критичные данные, то никаких "со стороны клиента" быть не должно. Нажат старт - на сервер отправилось "старт пошел", из данных в бд вычитается/прибавляется значение, обратно отсылается что в итоге получилось. С остальным так же - на сервер отправляется событие, а сервер считает чего куда прибавлять и возвращает результат на фронт.
    Ответ написан
    Комментировать
  • Можно ли на ноутбуке заменить процессор перепайкой если сокет один и тот же?

    @Lordofhell
    Сразу видно, ремонтников в чате нету. В первую очередь смотрим какой стоит чипсет, именно он определит что будет поддерживаться. Смотрит маркировку, дальше находим даташит на него и глядим там что он поддерживает. А уже потом можно слить Биос и глянуть наличие микрокодов конкретных экземпляров в нем.
    Глянул спецификации, поддерживаются 7 и 8 поколения. Ни про какое 10е там речи быть не может
    Ответ написан
  • Как сделать быстрое переключение между двумя wifi при отвале одного из них?

    SignFinder
    @SignFinder
    Wintel\Unix Engineer\DevOps
    То, что вы хотите - сделать нельзя.
    Точнее можно прикрутить какой-то скрипт, который например будет пинговать постоянно что-то и при пропадании пинга переключаться на другой WIFI.
    Но правильное решение - поставить нормальный маршрутизатор с одним WIFI, который будет иметь выход через 2 канала и он будет переключаться между ними в зависимости от условий.
    Ответ написан
    Комментировать
  • Что это за неведомый слот?

    @Grand_turizmo
    Любитель поэкспериментировать с пк
    Похоже кто-то из китайцев обрезал планку ddr и продаёт её как ssd
    Ответ написан
    7 комментариев
  • Пропала картинка иконки на панели задач, но на рабочем столе картинка есть?

    eapeap
    @eapeap
    Сисадмин, Беларусь
    Правой мышкой по "плохому" значку на панели задач - открепить от панели задач.
    Правой мышкой по "хорошему" значку на рабочем столе - закрепить на панели задач.
    Ответ написан
    4 комментария