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

    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 комментария
  • Почему нет взаимодействия между компьтерами, которые находятся в одной VLAN, но в разных подсетях?

    @Komrus
    CIO
    Если уж позанудствовать.
    Компьютеры находятся в ОДНОМ VLAN'е. Значит на Layer 2 (Ethernet) они повзаимодействовать могут. Например - L2 бродкасты от однгого компа будут долетать до второго.
    Осталось придумать - какой протокол поднять поверх Ethernet. Например - какой-нибудь старенький чистый NetBIOS/NetBEUI. И тогда компьютеры вполне смогут обмениваться информацией.

    То есть расширенный ответ:
    Если (например - в целях информационной безопасности) надо обеспечить гарантированное отсутствие взаимодейтсвие между компами - их надо в как минимум разные VLAN'ы убирать. В одном VLAN'е - невозможно гарантировать отсутствие взаимодействия.
    А если смотреть с точки зрения рядового пользователя, то для двух компов со штатным на данный момент стеком протоколов (TCP/IP поверх Ethernet) - то нахождение в разных IP подсетях будет препятствоовать ПРЯМОМУ взаимодействию штатными средствами (файлы по SMB гонять). При этом взаимодействие через какой-нибудь внешний сервер (Telegram, например) - в полный рост будет...
    Ответ написан
    1 комментарий
  • Как сделать полное кэширование базы данных?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Вопрос сформулирован по-дурацки, из серии преждевременной оптимизации. "У меня ещё ни базы, ни запросов, ни нагрузки и никогда не будет, но желаю чтобы всё летало!"

    Но тем не менее, ответ на него существует. И он гораздо проще, чем все извращения, которые тут наперебой предлагают всякие доброхоты.

    Во-первых, увеличить innodb_buffer_pool_size до 80% от доступной памяти на сервере. Mysql совсем не дура, и прекрасно сама подтянет используемые таблицы в оперативку. И вселенская проблема нашего фантазёра будет решена.
    Отдельно здесь следует упомянуть случай, когда этому буферу не просто задан недостаточный размер, а жалкие 128 мегабайт, поскольку никто не догадался поменять значение, стоявшее в конфиге по умолчанию.

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

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Все специалисты ИТ смежные, почти никто не работает в чисто ИТ, все занимаются автоматизацией какой-то области человеческой деятельности. Естественно, чем лучше знаешь прикладную область, тем лучше решения способен разрабатывать. Так что в автоматизации медицины образование и опыт врача будут полезны. Однако, они не обязательны, многие из нас регулярно прикладную область меняют и изучают новую с нуля.
    Ответ написан
    Комментировать
  • Какая скорость передачи отдельного пакета по сети?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    Паузы во времени между пакетами для передачи пакетов из других потоков или те же самые ограничения на пропускную способность. А так же между отдельными сигналами кодирующими биты во время передачи. Поток состоит из времени передачи пакетов и пауз между пакетами. Соответственно пропускная способность - это объём данных переданных за определённое время. Пакет и байты в нём передаются всегда с максимальной скоростью, которую может выдать оборудование, поэтому и получается, что для отдельного пакета доступна вся скорость канала. А вот уже потоки делят канал друг с другом.
    Ответ написан
    Комментировать
  • Какая скорость передачи отдельного пакета по сети?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Как скорость передачи отдельного пакета может быть 100 Гбит/, если этот пакет передается в потоке со скоростью 50 Гбит/с?

    Элементарно. Ограничение скорости отдельного потока в канале - оно внешнее по отношению к скорости передачи данных в канале. За счёт конкуренции, шейпинга, приостановки средствами управления потоком... то есть канал половину времени передаёт данные потока со скоростью 100Гбит, а вторую половину или передаёт что-то другое, или ничего не делает, только держит несущую. А сама скорость в канале постоянна и неизменна.
    Ответ написан
    Комментировать
  • Почему i? Почему переменную, используемую в циклах, обычно называют именно i?

    15432
    @15432
    Системный программист ^_^
    Пошло из математики (Xi, Yj), продолжилось в Фортране (начиная с имени i переменные по умолчанию интовые были), потом все как-то привыкли
    Ответ написан
    Комментировать
  • Говорят,что не надо знать матем. при изучении программирования, но почему все задачи математические?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Потому что эти задачи придумали те, кто любит раздувать собственную важность и претендовать на обладание сакральным знанием. Попробуйте сменить источник учебного материала.
    Ответ написан
    Комментировать
  • Определение значений передаваемой в функцию переменной типа массив?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Это один из тех вопросов новичков, на который нельзя давать прямой ответ. Он превратится в пустое умствование и говнокод. Соглашусь с комментарием Дмитрий: тут просто не нужен массив. И тем более не нужно городить огород из абстракций. Тут явно нужен банальный VO/DTO, а автору надо перестать пытаться заворачивать привычные массивы в солидно выглядящие объекты, и начать использовать сами объекты.

    Если нам нужна конкретная структура, то и описываем её в конкретном классе, безо всяких интерфейсов:

    final readonly class Parameters
    {
        public function __construct(
            public string $key1,
            public int $key2,
            public DateTimeImmutable $key3,
        ) {}
    }
    public function execute(Parameters $parameters):


    В итоге у "стороннего разработчика" есть готовая документация - простое и понятное определение класса, экземпляр которого он должен передать в ваш метод. И уже на этапе создания этого объекта РНР надаёт разработчику по рукам, если хоть какое-то свойство не будет задано, или будет не того типа. При желании можно в конструктор добавить дополнительную валидацию, если просто типа недостаточно.

    При этом если внутри execute() вдруг зачем-то понадобится обратиться к свойствам именно как к массиву, то использовать волшебную функцию get_object_vars().

    Если же речь про валидацию входящих данных, то это вообще совсем другой вопрос.

    Для этого есть либо стандартные валидаторы, когда на вход подаётся массив и набор правил, вот например как в ларавле, симфони или в десятке отдельно стоящих библиотек, а на выходе - или гарантированно валидная структура данных, или ошибка.

    Либо готовые библиотеки десериализации, когда входящий JSON автоматом мапится на существующий объект, и в итоге получается или либо гарантированно валидный объект, или ошибка.

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

    Adamos
    @Adamos
    Как паллиатив, можно просто создать своп-файл.
    Именно для того редкого момента, когда память вдруг нештатно выжрана, и БД умирает по ООМ.
    Пусть оно две минуты в неделю потормозит, зато все живы ;)
    Ответ написан
    2 комментария
  • Начинающий системный администратор. Вопрос по построению сети?

    Adamos
    @Adamos
    Для 1с сейчас не только Win-сервер не требуется, но и Windows в принципе.
    AD - это инструмент управления большими сетями, в малых он создаст больше проблем, чем решит.
    Сервер - это полезно для устранения бардака. Только не Win-сервер, конечно. Файловый, чтобы файло по машинам не валялось. А от шифровальщиков те места, куда пользователям все равно нужно писать, вы не защитите никакими волшебными палочками. Только бэкап (недоступный юзерам из тех самых соображений).
    Ну, и потихоньку отказываться от Винды тоже полезно и перспективно.

    P.S. И как совет начинающему сисадмину - не употреблять в планах слово "ставить", если речь не о бесплатном софте. За все, что поставлено, но не куплено - отвечает, внезапно, именно сисадмин. Вполне реальной уголовкой.
    Ответ написан
  • Когда каскадное обновление это плохо?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Когда каскадное обновление это плохо?

    Каскадное обновление - в большинстве случаев это... глупо.

    Вспомним, что это вообще такое.

    Имеется связь, реализованная внешним ключом. Некое поле (в общем случае - выражение) основной таблицы, уникально индексированное, является значением, на которое ссылается некое поле (или выражение) подчинённой таблицы (возможно, и той же самой).

    По смыслу в основной таблице это поле - как минимум уникально. То есть с точностью до NULL оно является идентифицирующим - то есть если в этом поле не NULL, то определённое значение однозначно идентифицирует строго одну запись. В большинстве случаев же поле в основной таблице, на которое установлена ссылка в подчинённой таблице, вообще является первичным ключом, соответственно не может быть NULL и является истинно идентифицирующим.

    Что же есть каскадное обновление? Это изменение связанного значения в подчинённой таблице, если изменяется значение основной таблицы. Ну то есть если изменяется (вспоминаем сказанное выше) значение первичного ключа или поля, объявленного уникальным. В основной таблице. Ага...

    Ну то, что изменение/корректировка значения поля первичного ключа есть bad practice (читай - дурь голимая), хорошо известно, обосновано и весьма логично. Нет, реально возможны ситуации, когда такая операция оправдана и имеет смысл - но такая ситуация абсолютно всегда одноразовая, и есть составная часть административного обслуживания. А если подобная надобность возникла на уровне пользователя, в рабочем процессе - то это гарантия наличия серьёзной ошибки в проектировании БД.

    Практически всё то же относится и к корректировке просто уникального поля. За исключением случая, когда выполняется каскадное изменение значения поля, которое в основной таблице получило значение NULL. То есть когда выполняемая операция по смыслу является не обновлением, а "мягким удалением" основной записи с каскадным удалением всех подчинённых. Правда, на вопрос, как отличить мягко каскадно-удалённые подчинённые записи от мягко явно-удалённых, и как определить, с какой основной записью была связана мягко удалённая подчинённая, не залезая в журнал или бэкап, ответа никто не даст. А получается, что даже в случае исключения всё делается через "универсальный интерфейс", то есть косяк в проектировании структуры имеется и в этом случае.

    Резюмирую. Если каскадное обновление необходимо, оно скорее всего маскирует недостатки и ошибки проектирования. А плохо это или хорошо - прикрывать дырку костылём,- решайте сами.
    Ответ написан
    Комментировать
  • Как значения из одного массива преобразовать в другой массив?

    vhood
    @vhood
    Не забывайте отмечать решения
    С помощью функций для работы с массивами и/или конструкций для итерации массивов.

    UPD:
    Если только configuration_value, то можно напрямую
    //$array - исходный массив
    //$configurationValue - новый массив
    $configurationValue = $array['configuration_value'];
    Однако смысла в этом никогда нет, только память расходовать. Значения по ключу можно получать там, где это нужно, не сохраняя их в отдельную переменную.
    Ответ написан
    Комментировать
  • Как происходит деплой функции на тестовый стенд?

    Hivemaster
    @Hivemaster
    Админ, который хочет программировать
    Зависит от выбранного разработчиками рабочего процесса и настроек пайплайна. Может автоматически запускаться сборка при появлении изменений в какой-то предопределённой ветке, а можно руками выбрать какую ветку собирать и нажать кнопку сборки.
    Ответ написан
    Комментировать
  • Стоит ли делать отдельный микросервис для Баз данных?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    1 микросервис - 1 БД


    Если БД используют несколько микросервисов, то (согласно философии микросервисов) это неправильно.
    В таком случае, выделяй отдельный микросервис-прослойку для БД. Но это будет уже не БД, а другой, полноценный сервис - со своими API, репозиторием, версионированием и т.д.
    Ответ написан
    5 комментариев
  • Стоит ли делать отдельный микросервис для Баз данных?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Кто то счетает это хорошей идеей, как возможность связать все сервисы

    Тем временем центральная идея микросервисов в том, чтобы связанность максимально снизить.
    Ответ написан
    Комментировать
  • Как задать запрос в базу mysql с массивом данных?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега MySQL
    Понятия не имею как с этим работать.
    Поскольку это даже не JSON, а сериализация средствами PHP, то единственный адекватный способ - получать все записи из БД, десериализовывать и в коде считать что нужно.
    Ответ написан
    2 комментария
  • Существуют ли такие шпионский программы?

    @rPman
    Это возможно, android для этого предоставляет все возможности, в т.ч. при заблокированном экране, даже видео снимать можно и root для этого не нужен, пример приложения ip webcam.

    Само собой, приложение для этого запрашивает соответствующий доступ и требует отключить оптимизацию электропитания для конкретного приложения.

    p.s. существуют очень убедительные доводы, что к примеру youtube (в данном случае скорее всего весь google apps фреймворк) да и любое приложение крупных соцсетей (фейсбук, vk,...) слушают микрофон постоянно, рекгируя как минимум по ключевым словам а скорее всего отправляя уже разобранный текст на сервера, для оптимизации рекламных алгоритмов или алгоритмов подбора контента (shorts/tiktok)
    Ответ написан
    3 комментария
  • Как научиться удерживать код в голове?

    xez
    @xez
    TL Junior Roo
    Никак.
    Если вам приходится чего-то там удерживать в голове, то это негодный, плохой код.
    Почитать:
    Декомпозиция
    Вонючий код
    Code Smells
    Ответ написан
    1 комментарий