Как справиться с обновлениями токов в спящем загрузочном спящем режиме?Также необходимо сделать приложение масштабируемым - PullRequest
0 голосов
/ 04 февраля 2019

Тип проекта: - Spring-boot JPA project

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

  @RestController
    public class IncrementController {

    @Autowired
    MyNumberRepository mynumberRepository;

    @GetMapping(path="/incrementnumber")
    public String incrementNumber(){    
        Optional<MyNumber> mynumber = mynumberRepository.findById(1);
        int i = mynumber.get().getNumber();

        System.out.println("value of no is "+i);
        i = i+1;
        System.out.println("value of no post increment is "+i);
        mynumber.get().setNumber(i);

        MyNumber entity = new MyNumber();
        entity.setId(1);
        entity.setNumber(i);

        mynumberRepository.save(entity);
        return "done";      
    }   
}

Сущность выглядит так: -

    @Entity
@Table(name = "my_number")
public class MyNumber {

    @Id
    private Integer id;

    private Integer number;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }
 }

Ниже представлен репозиторий: -

   public interface MyNumberRepository extends JpaRepository<MyNumber, Integer>{

   }

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

Также необходимо развернуть приложение в нескольких местах и ​​подключиться к одной и той же БД.т.е. проблема масштабируемости.

Спасибо, Рахул

Ответы [ 3 ]

0 голосов
/ 04 февраля 2019

Вышеупомянутое решение будет работать, но я чувствую, что вы делаете чрезмерную разработку для очень простой проблемы.Я бы рекомендовал использовать последовательность базы данных. Я чувствую, что ваше требование довольно простое. В вашем сервисе вы можете просто вызвать getnextvalue для последовательности и затем установить значение в поле Id. Таким образом, вам не нужно управлять блокировками.База данных сделает это за вас.

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

0 голосов
/ 04 февраля 2019

Вместо блокировки транзакции вы также можете использовать функцию Oracle sequence или MySQL «AUTO_INCREMENT», которая предотвращает повторный возврат любого идентификатора.

https://community.oracle.com/thread/4156674

Потоковая безопасностьMySql's Select Last_Insert_ID

0 голосов
/ 04 февраля 2019

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

public interface MyNumberRepository extends JpaRepository<MyNumber, Integer> {

  @Lock(LockModeType.PESSIMISTIC_WRITE)
  Optional<MyNumber> findById(Integer id);
}

А затем вам нужно сделать метод REST транзакционным, добавив @ Transactional

@RestController
public class IncrementController {

    @Autowired
    MyNumberRepository mynumberRepository;

    @Transactional
    @GetMapping(path="/incrementnumber")
    public String incrementNumber(){    
        Optional<MyNumber> mynumber = mynumberRepository.findById(1);
        int i = mynumber.get().getNumber();

        System.out.println("value of no is "+i);
        i = i+1;
        System.out.println("value of no post increment is "+i);
        mynumber.get().setNumber(i);

        MyNumber entity = new MyNumber();
        entity.setId(1);
        entity.setNumber(i);

        mynumberRepository.save(entity);
        return "done";      
    }   
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...