Совет дня от дядюшки Макса
При использовании транзакций и блокировок в работе с базой данных старайся получать записи в одинаковом порядке для избежания взаимной блокировки (Deadlock).
Например, мы разрабатываем кошелек, где у пользователей есть финансовые счета (accounts). Пользователь может совершать разные операции со счётом: пополнять (deposit), переводить другому пользователю (transfer) или выводить средства со счёта (payout).
Во всех этих операциях скорее всего нужно будет использовать транзакции и блокировки, чтобы другая параллельная транзакция не могла изменять эти записи в базе данных в тот же момент.
Так вот, в каждой такой транзакции нужно получать записи из базы в одинаковом порядке, чтобы не получился замкнутый круг из блокировок (deadlock).
Пример ошибки: в одной транзакции мы сначала получили и заблокировали счёт (account), а потом получили и заблокировали пополнение (deposit). В другой транзакции мы сделали тоже самое, но наоборот - сначала заблокировали deposit, а потом account. Если обе транзакции запустятся одновременно, то одна сначала заблокирует счёт, а вторая пополнение, затем первая попытается заблокировать пополнение, но оно уже заблокировано второй транзакцией, которая в этот момент пытается заблокировать счёт, который в свою очередь уже заблокирован первой транзакцией.
В такой ситуации успешно завершится только одна из транзакций, а вторая завершится с ошибкой.
Документация на примере PostgreSQL:
https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-DEADLOCKS
Ставь лайк, если полезно 👍 делись своим опытом в комментариях!
#db #deadlock #tip
При использовании транзакций и блокировок в работе с базой данных старайся получать записи в одинаковом порядке для избежания взаимной блокировки (Deadlock).
Например, мы разрабатываем кошелек, где у пользователей есть финансовые счета (accounts). Пользователь может совершать разные операции со счётом: пополнять (deposit), переводить другому пользователю (transfer) или выводить средства со счёта (payout).
Во всех этих операциях скорее всего нужно будет использовать транзакции и блокировки, чтобы другая параллельная транзакция не могла изменять эти записи в базе данных в тот же момент.
Так вот, в каждой такой транзакции нужно получать записи из базы в одинаковом порядке, чтобы не получился замкнутый круг из блокировок (deadlock).
Пример ошибки: в одной транзакции мы сначала получили и заблокировали счёт (account), а потом получили и заблокировали пополнение (deposit). В другой транзакции мы сделали тоже самое, но наоборот - сначала заблокировали deposit, а потом account. Если обе транзакции запустятся одновременно, то одна сначала заблокирует счёт, а вторая пополнение, затем первая попытается заблокировать пополнение, но оно уже заблокировано второй транзакцией, которая в этот момент пытается заблокировать счёт, который в свою очередь уже заблокирован первой транзакцией.
В такой ситуации успешно завершится только одна из транзакций, а вторая завершится с ошибкой.
Документация на примере PostgreSQL:
https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-DEADLOCKS
Ставь лайк, если полезно 👍 делись своим опытом в комментариях!
#db #deadlock #tip
👍14
Спасибо за лайки! Вот так бы всегда 😃
Как обещал прикладываю простой пример использования нашей функции
Смысл примера:
- У нас есть посты в блоге (как обычно =))
- Приходит запрос за списком постов (GET api/posts)
- В запросе могут быть параметры (категория, поиск, страница пагинации)
- Мы хотим кешировать результаты предыдущих запросов, чтобы не тревожить базу по пустякам
- Но нам нужен ключ для кеша, который зависит от параметров в запросе (категория, страница и поиск)
- Поэтому мы берём массив параметров из запроса (по сути - фильтров) и формируем из них подпись при помощи нашей функции
- Как вы помните,
Поэтому наш «отпечаток пальца» помогает нам сформировать ключ для кэша ($key) именно под этот запрос.
Надеюсь пример понятен. Если что обсуждаем вопросы в комментариях. Лайк! 🤝
#tip
Как обещал прикладываю простой пример использования нашей функции
fingerprint
, которая возвращает подпись массива.Смысл примера:
- У нас есть посты в блоге (как обычно =))
- Приходит запрос за списком постов (GET api/posts)
- В запросе могут быть параметры (категория, поиск, страница пагинации)
- Мы хотим кешировать результаты предыдущих запросов, чтобы не тревожить базу по пустякам
- Но нам нужен ключ для кеша, который зависит от параметров в запросе (категория, страница и поиск)
- Поэтому мы берём массив параметров из запроса (по сути - фильтров) и формируем из них подпись при помощи нашей функции
- Как вы помните,
fingerprint
сначала сортирует массив по ключам, поэтому результат всегда будет одинаковый НЕ зависимо от порядка элементов в массиве.Поэтому наш «отпечаток пальца» помогает нам сформировать ключ для кэша ($key) именно под этот запрос.
Надеюсь пример понятен. Если что обсуждаем вопросы в комментариях. Лайк! 🤝
#tip
👍13
Хай, гайз! Делюсь с вами еще одной фишкой из старого проекта.
Что имеем
1. Обычное html-поле
2. Проект на Laravel + Livewire-компонент с формой для пользователя.
3. Шаблон на старом добром
Задача
1. Определять страну пользователя по IP-адресу.
2. Автоматически выбирать эту страну в
3. Если страна у пользователя уже выбрана ранее, то ничего делать не нужно.
Решение
1. При загрузке страницы делаем GET-запрос на сервис
2. Если удалось получить страну, то устанавливаем её код (например RU) в качестве значения для соответсвующего свойства нашего Livewire-компонента (благо в базе ID стран - это их ISO-коды)
3. Магия Livewire автоматически выбирает эту страну в селекте благодаря реативности через
Профит! И лайк 🤗
#laravel #livewire #tip
Что имеем
1. Обычное html-поле
select[type="country_id"]со списком стран.
2. Проект на Laravel + Livewire-компонент с формой для пользователя.
3. Шаблон на старом добром
Bootstrap 4 + jQuery(купленый шаблон).
Задача
1. Определять страну пользователя по IP-адресу.
2. Автоматически выбирать эту страну в
selectв нашем компоненте.
3. Если страна у пользователя уже выбрана ранее, то ничего делать не нужно.
Решение
1. При загрузке страницы делаем GET-запрос на сервис
ipinfo.ioдля определения страны пользователя по его IP (бесплатный тариф до 50к запросов в месяц).
2. Если удалось получить страну, то устанавливаем её код (например RU) в качестве значения для соответсвующего свойства нашего Livewire-компонента (благо в базе ID стран - это их ISO-коды)
3. Магия Livewire автоматически выбирает эту страну в селекте благодаря реативности через
wire:model="country_id".
Профит! И лайк 🤗
#laravel #livewire #tip
👍10
Адаптивное видео (пропорции)
Продолжаем тему вёрстки. Иногда нам нужно сделать адаптивное видео (или другой элемент с соблюдением пропорции - отношение ширины к высоте).
У этой задачи есть классическое решение - использовать абсолютное позиционирование и верхний внутренний отступ (например padding-top: 56.25%).
Однако не многие знают (мы теперь знаем!), что есть CSS-свойство aspect-ratio, которое как раз решает эту задачу очень просто 👇
https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
Кстати, Tailwind конечно имеет удобные классы для работы с этим свойством, например aspect-video - и адаптивное видео 16/9 готово! Так просто 😃 На сайте можно подвигать видео за ползунок справа от него и убедиться, что оно адаптивное 👇
https://tailwindcss.com/docs/aspect-ratio
Поддержка браузерами в принципе НЕ плохая - 86%. Все версии браузеров, выпущеные с 2021 года поддерживают:
https://caniuse.com/?search=aspect-ratio
Будем иметь ввиду!
#html #css #tailwind #tip
Продолжаем тему вёрстки. Иногда нам нужно сделать адаптивное видео (или другой элемент с соблюдением пропорции - отношение ширины к высоте).
У этой задачи есть классическое решение - использовать абсолютное позиционирование и верхний внутренний отступ (например padding-top: 56.25%).
Однако не многие знают (мы теперь знаем!), что есть CSS-свойство aspect-ratio, которое как раз решает эту задачу очень просто 👇
https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
Кстати, Tailwind конечно имеет удобные классы для работы с этим свойством, например aspect-video - и адаптивное видео 16/9 готово! Так просто 😃 На сайте можно подвигать видео за ползунок справа от него и убедиться, что оно адаптивное 👇
https://tailwindcss.com/docs/aspect-ratio
Поддержка браузерами в принципе НЕ плохая - 86%. Все версии браузеров, выпущеные с 2021 года поддерживают:
https://caniuse.com/?search=aspect-ratio
Будем иметь ввиду!
#html #css #tailwind #tip
👍10
Хелперы для вывода даты и времени
Часто на проекте нужно выводить дату или время в определённом формате.
Так же в мультиязычных проектах формат даты и времени может отличаться в зависимости от языка сайта.
Если в будущем придёт задача изменить формат, то придётся:
- Искать все места в проекте.
- Менять вручную и тестировать.
- Надеяться, что ничего не пропустил.
Поэтому я сразу помещаю логику форматирования даты/времени в функции-хелперы (на скрине).
Вывожу дату/время везде через эти функции и потом, при необходимости, могу менять формат в любой момент в одном месте. Или использовать там условия, чтобы формат зависел от языка сайта.
Пример использования:
Планирую создать отдельный telegram-канал с такими полезными советами, примерами моего кода, короткими практическими видео и лайфхаками из моего личного опыта.
Лайк?
#laravel #tip #date #time #helpers
Часто на проекте нужно выводить дату или время в определённом формате.
Так же в мультиязычных проектах формат даты и времени может отличаться в зависимости от языка сайта.
Если в будущем придёт задача изменить формат, то придётся:
- Искать все места в проекте.
- Менять вручную и тестировать.
- Надеяться, что ничего не пропустил.
Поэтому я сразу помещаю логику форматирования даты/времени в функции-хелперы (на скрине).
Вывожу дату/время везде через эти функции и потом, при необходимости, могу менять формат в любой момент в одном месте. Или использовать там условия, чтобы формат зависел от языка сайта.
Пример использования:
{{ __datetime($order->created_at) }}
{{ __date($order->created_at) }}
{{ __time($order->created_at) }}
Планирую создать отдельный telegram-канал с такими полезными советами, примерами моего кода, короткими практическими видео и лайфхаками из моего личного опыта.
Лайк?
#laravel #tip #date #time #helpers
👍34