20 августа 2026
Алексей ЗотовПредпочитаю ломбок. Не удобно с рекордами ориентироваться в коде
В DDD record идеален для доменных сущностей с инвариантами
Алексейтекст ещё не в индексе
Именно по этой причине у всех работающих с разными СУБД библиотек есть классы-адаптеры под разные СУБД.
Для Oracle есть родной оператор merge под эту задачу, который может до завершения транзакции залочить апдейтом существующую запись или заинсертить новую.
Павел Java 300k/nsexТогда можно попробовать ловить ошибку и делать get
Ну выглядит будто как костыль, мало того, что придется отлавливать определенный тип исключений, так ещё придётся проверять что его выкинул именно нужный тебе constraint а не какой то соседний
АлексейНу выглядит будто как костыль, мало того, что придется отлавливать определенный тип исключений, так ещё придётся проверять что его выкинул именно нужный тебе constraint а не какой то соседний
Это не костыль, а скорее единственный вариант в твоем случае) если делать на чистом жпа
АлексейСофт ставится на стороне клиента, у каждого клиента свой стек
я бы упоролся тупо
@Transactional
public Entity getOrCreate(String code) {
Entity entity = repository.findByCode(code);
if (entity != null) {
return entity;
}
try {
Entity created = new Entity(code);
repository.saveAndFlush(created);
return created;
} catch (PersistenceException ex) {
// кто-то успел вставить раньше
return repository.findByCode(code);
}
}
в идеале конечно завязаться на конкретные on conflict, merge и тд
22 августа 2026
Алексейтекст ещё не в индексе
Для разрешения конфликтов при вставке создаётся доп таблица (сущность) блокировок. Одна строка в ней соответствует целевой таблице.
Дальше при обработке:
1 Попытка селекта строки бизнес таблицы с блокировкой. Если строка найдена то обработка, иначе
2 Блокировка строки в таблице блокировок (селект с блокировкой)
3 повторная попытка селекта строки бизнес траблицы с блокировкой (за это время строка могла уже появиться). Если строка найдена, то обработка, иначе
4 вставка строки
В целом это реализация паттерна синглтон с блокировкой через бд, реализуемо на jpa. Если отойти от чистого jpa, то можно обойтись без доп таблицы блокировок и лочить целиком целевую бизнес таблицу
Фотография
нажмите — покажем
нажмите — покажем
🔥 Хочешь быстрее расти в IT? Хватит учиться в одиночку
Окружение решает больше, чем кажется.
Собрал папки и каналы, где можно быстрее влиться в нужное направление, следить за трендами и не вариться в своём пузыре.
AI: t.me/ai_machinelearning_big_data
Python: t.me/pythonl
Linux: t.me/linuxacademiya
Хакинг: t.me/linuxkalii
DevOps: t.me/DevOPSitsec
Docker: https://t.me/+90Z5TAyfuNU5YmRi
Golang: t.me/Golang_google
Rust: t.me/rust_code
C++: t.me/cpluspluc
C#: t.me/csharp_1001_notes
Java: t.me/javatg
JavaScript: t.me/javascriptv
React: t.me/react_tg
Frontend: t.me/front
PHP: t.me/phpshka
Android: t.me/android_its
Мобильная разработка: t.me/mobdevelop
Базы данных: t.me/sqlhub
Data Science: t.me/data_analysis_ml
Big Data: t.me/bigdatai
Математика: t.me/data_math
Физика: t.me/fizmat
Kubernetes: t.me/kubernetc
GameDev: https://t.me/gamedev
Haskell: t.me/haskell_tg
Собеседования и карьера:
DS собеседования: t.me/machinelearning_interview
Python собеседования: t.me/python_job_interview
Папка с вакансиями: t.me/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: t.me/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.me/addlist/eEPya-HF6mkxMGIy
Папка ML: https://t.me/addlist/2Ls-snqEeytkMDgy
Папка Frontend: https://t.me/addlist/mzMMG3RPZhY2M2Iy
Полезное сверху:
ИТ-мемы: t.me/memes_prog
Английский для программистов: t.me/english_forprogrammers
ИИ и технологии: t.me/vistehno
954 ГБ open-source курсов: https://t.me/+rKBQEMccAA01MTcy
ИТ-книги бесплатно: https://t.me/addlist/BkskQciUW_FhNjEy
Max Ai: https://max.ru/ai_machinelearning_big_data
Max python: https://max.ru/pythonl
ТЕХНО: https://max.ru/vistehno
Max Go: https://max.ru/Golang_google
Max Linux: https://max.ru/linuxkalii
Devops: https://max.ru/DevOPSitsec
C#: https://max.ru/csharp_ci
C++: https://max.ru/cpluspluc
SQL: https://max.ru/sqlhub
Java: https://max.ru/javatg
Подписывайся на нужные направления и собирай себе ленту, которая реально двигает вперёд.
1.6K · Aleksey SДля разрешения конфликтов при вставке создаётся доп таблица (сущность) блокировок. Одна строка в ней соответствует целевой таблице.
Дальше при обработке:
1 Попытка селекта строки бизнес таблицы с блокировкой. Если строка найдена то обработка, иначе
2 Блокировка строки в таблице блокировок (селект с
Спасибо. Это звучит как вариант, но конечно надо будет проверять насколько высокий уровень параллелизма можно будет удержать данной схемой
АлексейСпасибо. Это звучит как вариант, но конечно надо будет проверять насколько высокий уровень параллелизма можно будет удержать данной схемой
В данной схеме нет чего либо, что могло бы ограничить параллельную работу. Если ситуация, когда разные потоки будут одновременно хотеть изменить/вставить один объект частая, то будут ждать друг друга в очереди, но без этого никуда
Aleksey SВ данной схеме нет чего либо, что могло бы ограничить параллельную работу. Если ситуация, когда разные потоки будут одновременно хотеть изменить/вставить один объект частая, то будут ждать друг друга в очереди, но без этого никуда
Ну я эти и имел ввиду, на нашей системе надо будет проверить насколько часто случаются такие ситуации, и сколько в худшем случае будет висеть поток
АлексейНу я эти и имел ввиду, на нашей системе надо будет проверить насколько часто случаются такие ситуации, и сколько в худшем случае будет висеть поток
Есть ещё вариант для случая если потокам, приносящим объекты, не требуется сразу же знать их новое состояние, а задача только сохранить. Тогда можно дампить объекты в отдельную таблицу без блокировок, а отдельным асинхроным потоком собирать всё новоприбывшее и сливать в целевую запись
Фотография
нажмите — покажем
нажмите — покажем
⚡️ Spring Boot 4: `@ConfigurationPropertiesSource` для типов из других модулей
В Spring Boot 4 появилась полезная штука для конфигурации больших проектов.
@ConfigurationPropertiesSource позволяет генерировать metadata для типов, которые находятся не в текущем модуле, а, например, в общей библиотеке или отдельном starter-модуле.
Раньше с такими внешними типами IDE-подсказки для application.yml и application.properties могли быть неполными или вообще отсутствовать.
Теперь можно явно указать источник конфигурационных свойств и получить нормальную metadata даже для внешних классов.
Особенно полезно для:
— multi-module проектов
— внутренних Spring Boot starter'ов
— shared configuration libraries
— больших платформенных команд
Мелкая фича, но для DX в крупных Spring Boot проектах очень приятная.
#SpringBoot4 #Config
2K · 24 августа 2026
Фотография
нажмите — покажем
нажмите — покажем
🖥 Java: почему 1.234,56 ломает Double.parseDouble()
В Java число - это не всегда просто строка с точкой.
Например:
Double.parseDouble("1.234,56");
закончится NumberFormatException.
Проблема в локали: в разных странах . и , означают разное.
Для таких случаев лучше использовать:
NumberFormat format =
NumberFormat.getInstance(Locale.ITALY);
Number value = format.parse("1.234,56");
double n = value.doubleValue();
Получим:
1234.56
Главное правило: если число пришло от пользователя, из CSV или внешней системы — сначала узнай его locale.
Иначе можно получить не только ошибку, но и тихо распарсить совсем не то число.
2K · 26 августа 2026
Фотография
нажмите — покажем
нажмите — покажем
Java-ловушка: . в формате числа не всегда означает точку
В DecimalFormat шаблон вроде:
#,###.##
не гарантирует вывод 1,234.56.
Символы зависят от locale:
🇺🇸 US → 1,234.56
🇮🇹 Italy → 1.234,56
Поэтому если формат предназначен для конкретной страны, лучше задавать её явно:
DecimalFormatSymbols it =
new DecimalFormatSymbols(Locale.ITALY);
DecimalFormat format =
new DecimalFormat("#,###.##", it);
Иначе приложение может внезапно начать форматировать числа иначе просто потому, что JVM запустили с другой локалью.
Мелочь, которая особенно неприятно всплывает в деньгах, отчётах и CSV.
1.9K · 28 августа 2026
Фотография
нажмите — покажем
нажмите — покажем
🚀 Spring Boot 4 упростил работу с MongoDB health checks
Теперь для проверки состояния MongoDB больше не нужен Spring Data.
Что изменилось:
- health indicators переехали в spring-boot-mongodb
- работают напрямую с MongoDB driver
- для /actuator/health достаточно spring-boot-starter-mongodb
- Spring Data подключать не обязательно
То есть если сервис работает с MongoDB напрямую через драйвер, health check всё равно можно получить без лишней зависимости.
Полезное изменение для более лёгких Spring Boot 4 сервисов.
1.6K · 30 августа 2026
Фотография
нажмите — покажем
нажмите — покажем
💡 Java: не используй `Thread.sleep()` для ожидания работы
Thread.sleep() - это просто пауза на заданное время.
Проблема в том, что ты угадываешь:
❌ поток может проснуться слишком рано
❌ или наоборот, ждать дольше, чем нужно
❌ polling через sleep() создаёт лишние задержки и проверки
Для координации потоков лучше использовать:
✅ wait() / notify()
✅ CountDownLatch
✅ другие примитивы синхронизации из java.util.concurrent
Например:
CountDownLatch done = new CountDownLatch(1);
done.await(); // ждём сигнал
done.countDown(); // работа завершена
А если задача должна выполняться периодически, вместо бесконечного цикла с sleep() лучше взять
ScheduledExecutorService exec =
Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(
this::doWork,
0,
1,
TimeUnit.SECONDS
);
Thread.sleep() хорошо подходит для простой задержки.
Для ожидания события и периодических задач в Java есть более точные инструменты.
#Java #Concurrency
1.3K · 1 сентября 2026
Фотография
нажмите — покажем
нажмите — покажем
Spring Boot 4: консольные логи теперь можно отключить одной настройкой.
logging:
console:
enabled: false
Полезно для продакшена и контейнеров, где логи уходят не в stdout, а, например, в файл или через OTLP.
При этом остальные способы логирования можно оставить:
• file appender
• удалённый сбор логов
• OTLP
• собственные appenders
Удобная мелочь, которая позволяет не городить отдельную конфигурацию Logback только ради отключения консоли.
827 ·