Size: a a a

Spring Framework and more

2020 June 09

VG

Vladislav Gerasimov in Spring Framework and more
Подскажите, пожалуйста..
Есть OncePerRequest Filter, в котором, допустим, в каждом запросе выполняет проверку в БД (в фильтре инжектится сервис) и, если там нету записи, то выполняет внешний рест вызов и записывает в БД.
Но клиент бекенда потенциально шлет асинхронные запросы (например, три) один за одним, срабатывают у всех проверки в фильтре, записи нету, у всех отправляется внешний запрос и сохраняются сразу три записи.
Нужно синхронизировать запросы, вызвать внешний сервис один раз и один раз сохранить запись.
Смотреть в сторону изоляции транзакции?
источник

RS

Ruslan Stelmachenko in Spring Framework and more
Проверка, есть ли запись, выполняется же по какому-то ключу? Этот ключ должен быть уникальный. А если он будет уникальный, то 2-й инсерт и так не пройдет, т.к. будет duplicate key.

Другое дело, что у вас там еще "то выполняет внешний рест вызов ". Вот с этим ACID никак не поможет. Даже если второй инсерт не пройдет, и транзакция откатится, рест-вызов уже ушел. Если это не допустимое поведение, то нужно выносить рест-вызов за пределы транзакции. Но тогда может транзакция закоммититься, а потом core dump/вырубили свет/etc и рест-вызов не ушел. В общем тут классическая проблема распределенных транзакций получается, и если надо прям чтобы было либо все, либо ничего, то надо SAGA-паттерн юзать, например. Т.е. все становится намного сложнее и на практике обычно на проблему "ну а вдруг core dump" все просто забивают.
источник

VG

Vladislav Gerasimov in Spring Framework and more
Filter extends OncePerRequestFilter {
    Service service;

    doFilter() {
        service.check();
       chain.doFilter(...);
    }
}

Service {
   @Transactional
    public check() {
          if (repo.find(...)) return;
          restClient.get();
          repo.save();
   }
}

Схематично так
источник

VG

Vladislav Gerasimov in Spring Framework and more
спасибо!
источник

М

Михаил in Spring Framework and more
можно попробовать через ReentrantLock по условию блокировать вызовы к внешнему апи, если блокировка не удалась, значит один из потоков держит лок и выполняет внешний вызов. но тут уже зависит что дальше от логики требуется, что будет если работающий поток отвалится, или вернется не то что надо, не сохранится и тд. это конечно если цель снизить колво обращений к внешнему сервису
источник

RS

Ruslan Stelmachenko in Spring Framework and more
Если скалировать сервис не предполагается, то лок конечно может помочь. Но не просто ReentrantLock, т.к. тогда это будет узким местом всей системы. тут надо хотя бы набор из N локов, которые берутся по хэшу ID из мапы или что-то в этом роде. В Гуаве для этого отдельный класс есть: Striped.

Но как только нужно поднять не 1, а 2 инстатса сервиса, все эти локальные локи сразу идут нафик.
источник

М

Михаил in Spring Framework and more
Да, я не написал что его надо крайне аккуратно использовать и не в одном экз)) спасибо
источник

М

Михаил in Spring Framework and more
Если не особо критично, можно в принципе запилить очередь с асинхронной регистрацией и сохранением, но это может оказаться как из ружья по мухам стрелять, если сервис простой
источник

AA

Alexey Astashenko in Spring Framework and more
Если предполагается скалирование, можно использовать распределенные локи, но нужно тогда доп сервис какойнибудь использовать. типа хазелкаста ( у него удобные локи есть, которые имплементят Lock из java concurrent), либо redis с redisson-ом
источник

VG

Vladislav Gerasimov in Spring Framework and more
Спасибо за советы!
источник
2020 June 10

Д

Дима in Spring Framework and more
о
источник

Д

Дима in Spring Framework and more
20 минут назад такого же бота видел
источник

KD

Konstantin Degtyar in Spring Framework and more
ВАХ, хорошая попытка
источник

KD

Konstantin Degtyar in Spring Framework and more
банить надо за такие посты
источник

Ю

Юрий in Spring Framework and more
spring:
 cloud:
   gateway:
     httpclient:
       connect-timeout: 20000
     discovery:
       locator:
         enabled: true
     routes:
       - id: oauth-server
         uri: lb://oauth-server
         predicates:
           - Path=/auth/**
         filters:
           - StripPrefix=1


Добрый дент, я хочу в гетвей добавить роут который по localhost:8000/api/news будет перенаправлять на 192.168.2.4 как это сделать?
источник

ЮЮ

Юрий Юрий in Spring Framework and more
Всем привет, подскажите в Java есть уже готовая константа
new SimpleDateFormat("yyyy-MM-dd")  ?
источник

MW

Mary Warren in Spring Framework and more
Only God know how I feel for what have happened to me for the pass weeks through the helped of this man now I can buy what I like now follow him and see your success
https://t.me/joinchat/AAAAAFckJ3myY8FjUWbmYQ
источник

М

Михаил in Spring Framework and more
Юрий Юрий
Всем привет, подскажите в Java есть уже готовая константа
new SimpleDateFormat("yyyy-MM-dd")  ?
в новом java time DateTimeFormatter.ISO_DATE
источник

ЮЮ

Юрий Юрий in Spring Framework and more
Михаил
в новом java time DateTimeFormatter.ISO_DATE
Видел, просто мне надо от туда Date брать, но сильно длинно выходит
Date date = Date.from(Instant.ofEpochSecond(LocalDate.parse("2020-01-02", DateTimeFormatter.ISO_DATE).toEpochDay()));
источник

A

Anes in Spring Framework and more
Всем привет. Проблема такая - https://hastebin.com/upunamuxaj.css . Приложение работает и в какой то момент ложится. Пытался гуглить максимум что понял что какая то трабла с рекурсией. Причем ложится на разных методах, может на containsHeader, getUserPrincipal ему не принципиально.
источник