Pull to refresh
4
0
Truck Fudeau @oxff

Team Lead, Senior Java Developer, DevOps, DBA

Спасибо что поделились вашим опытом. Вижу что в планах у вас есть тесты, а без них я бы не рискнул использовать подобный инструмент.

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

А вы уберите @Modifying. Строго говоря, тут уже не совсем DML, но микс из DML+DQL. Данная аннотация просто изменяет способ интерпретации результата запроса.

Можете нагуглить на эту тему много интересного и на stackoverflow и github issues. У меня такой код есть в продакшн, и никаких блокировок не нужно.

NativeQuery возвращает количество измененных строк, а не сохраненный объект. Чтобы получить этот объект, нам надо выполнять отдельный запрос в БД, и при этом нет гарантий, что мы получим ровно то, что сами только что вставили;

Вы используете синтаксис Postgres. Просто допишите в конец "returning *" и DML запрос вернёт строки, подвергшиеся изменению.

Я просто решил пояснить для задавшего вопрос. Что это не техническое ограничение существующих решений, а скорее жизненная необходимость. Две ноды это однозначно ручной фэйловер.

Тут всё упирается в кворум. Можно иметь 2 ноды БД с автофэйловером, но потребуется как минимум 3 ноды DCS (etcd и т.п.).

Без третьей ноды/свидетеля не разрулить split brain.

Извините, но я никак не пойму в чём у вас проблема. В соответствии с документацией, для авто-инкрементных полей не нужно писать дополнительного кода вообще. У вас ведь Postgres, почему вы не можете просто объявить поля соответственно, используя легаси SERIAL или современный GENERATED ... AS IDENTITY?

Сиквенс у вас уже есть, и вы его пытаетесь использовать. А тип SERIAL это просто синтаксический сахар, который создаёт сиквенс и объявляет поле как NOT NULL DEFAULT nextval('seq_name')

Плюс этого в том, что вам не нужно делать дополнительный запрос к БД для получения ID.

Какая-то несусветная чушь. При чём тут Java вообще? Возьмите СУБД с другой реализацией мультиверсионности, или совсем без неё, блокировочник, и затем повторите тест.

И кстати, наличие этого "мусора" в Postgres имеет и свои преимущества. Например, не нужно иметь дополнительное место для хранения версий строк или undo data; отмена транзакции происходит мгновенно потому что оригинальные версии строк всё ещё присутствуют; транзакционное изменение схемы данных (DDL) и хранимых процедур с возможностью отмены; нет проблемы переполнения для транзакций изменяющих много данных и т.д. Мусором это становится если автовакуум не поспевает, как правило по причине того что его не настрили как следует под конкретное приложение.

В данном случае и пессимистическая блокировка на уровне строки (SELECT ... FOR UPDATE) не всегда помогает, если нужно обновлять несколько строк в одной транзакции. Нужно чётко следить за порядком строк, чтоб не нарваться на deadlock.

Надёжнее вынести код в хранимую процедуру PL/pgSQL и использовать блокировку критической секции кода при помощи pg_advisory_xact_lock() и т.п. Это как synchronized только в Postgres. В итоге имеем простейшую хранимку в пару строчек и транзакционную @Procedure в Repository спринга.

Постгрес поддерживает шардирование при помощи комбинации партиционирования + FDW. Каждая секция таблицы смотрит на свой foreign server (который может быть HA кластером)

Интересненько! Я и говорю, это уже получается не формальный научный подход, а оценочное суждение 🙂 Похоже на подгон результата под требования заказчика.

Не могу с вами согласиться. Это звучит довольно субъективно и оценочно. Не думаю, что это можно формализовать, измерить, и включить в статистику.

Кроме того, перед моими глазами много примеров того, как сотрудники, выполняющие качественно свою неинтеллектуальную шаблонную работу, ценятся, и получают достойную компенсацию. Они надёжны, на них можно положиться. Мечта управленца.

Здесь имеется в виду, конечно же, English literacy. Многие из этих людей хорошо владеют родным письменным языком. Им английский по сути вообще не нужен, потому что они живут и работают в этнических комьюнити.

Отличная серия статей, спасибо, @ppetrov91!

В разделе про фэйловер у вас не упомянут "pg_auto_failover" от Microsoft/Citus. Я не первый раз обращаю внимание на то, что это решение незаслуженно обходится стороной. Для этого есть какая-то причина или его просто забыли?

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

Реже присылают SMS. Вот например сегодня получил такое. Код страны +1, чтоб не вызвать у меня подозрений, но они умеют подставлять любые номера, даже правительственные.

Хотите поболтать с Sharon? Телефончик вы знаете :-)

Всё хорошо с null.

concat_ws('-', 'A', 'B', null, 'D') вернёт 'A-B-D'

Spring Data или сам Hibernate могут быть достаточно умны, что бы поместить из в так называемый Bath и отдать их в СУБД за один раз, но для этого id новых записей надо знать за ранее, вот тут то и вступает в игру тот самый автоинкремент, запросив текущее значение счетчика, не трудно догадаться какие id будут у всех пяти записей.

  1. "Bath" переводится на русский как "ванна". Скорее всего, вы имели в виду слово "batch".

  2. "за ранее" -> "заранее"

  3. На самом деле "догадаться" очень трудно, потому что в общем случае СУБД обслуживает несколько коннектов одновременно, и в момент когда несколько сессий запросят несколько значений из sequence, каждая из них может получить монотонно нарастающий набор пересекающихся значений. Например, сессия 1 получит "1, 2, 5, 6" и сессия 2 получит "3, 4, 7, 8".

    Дальше не стал читать, сорри.

А лучше купить стол переменной высоты и работать стоя большую часть времени. Я первый раз сажусь во время обеда, потом снова работаю стоя, и лишь последний час работаю сидя. У меня совсем прошла спина. Иногда, правда, бывают дни когда по какой-либо причине сил стоять весь день нет, тогда я сижу примерно половину рабочего времени.

Дядя Боб (Robert C. Martin) идёт ещё дальше, и говорит:

Функция должна делать лишь одну вещь. Что такое "одна вещь"? Функция делает одну вещь если из неё невозможно извлечь другую функцию. Нужно последовательно извлекать функции до тех пор, пока это не станет уже невозможно. Каждой функции следует давать осмысленные, выразительные, удобопроизносимые имена, и помещать их в должным образом названные классы, пакеты и модули (правило касательно длины имён я привёл в предыдущем комменте).

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

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

Просто прочтите это (для доступа в сайту требуется VPN, спасибо Рокомнадзору):

https://refactoring.guru/ru/smells/long-method

Цитата:
Следует придерживаться такого правила: если ощущается необходимость что-то прокомментировать внутри метода, этот код лучше выделить в новый метод. Даже одну строку имеет смысл выделить в метод, если она нуждается в разъяснениях. К тому же, если у метода хорошее название, то не нужно будет смотреть в его код, чтобы понять, что он делает.

По поводу длины имён есть простое правило. Длина имени метода или класса обратно пропорциональна размеру его области действия (scope). Для переменных всё наоборот - чем меньше область, тем короче имя.

Information

Rating
Does not participate
Location
Montreal, Quebec, Канада
Registered
Activity

Specialization

Backend Developer, Database Architect
Lead
From 250,000 $