Как сделать потокобезопасный контроллер в весенней загрузке
Как я должен создать контроллер, который является потокобезопасным?
В соответствии с лучшей практикой контроллеры являются синглтон.
Рассмотрим приведенный ниже код, в котором я сохраняю пользовательские данные через автосервисный объект Object, что делает мой код сохраняющим состояние. Как бы я сделать приведенный ниже поток кода безопасным.
@RestController
class ApiController {
@Autowired
IDbService< User > iDBService;
@RequestMapping(value = "/api/adduser", method = RequestMethod.POST)
public ResponseEntity<User> createUser(@RequestBody User user){
User savedUser=iDBService.create(user);
return new ResponseEntity<User>(savedUser, HttpStatus.CREATED);
}
Вот моя реализация сервиса. Я поделился переменной в моем сервисе
public class IDbServiceImpl<T> implements IDBService<T>{
@Autowired
GenericRepository<T, Serializable> genericRepository;
@Override
public T create(T object) {
return genericRepository.save(object);
}
}
3 ответа
Ваш контроллер по умолчанию одноэлементный, а сервис по умолчанию тоже одноэлементный.
Поэтому, чтобы сделать их потокобезопасными, вы должны убедиться, что операции, выполняемые внутри службы, должны быть потокобезопасными в случае изменения состояния объекта внутри службы, т.е. список.
В случае использования rdbms у вас есть проблема, связанная с транзакцией.
Если вы используете Spring и Jpa, менеджер транзакций позаботится о ваших обновлениях, если вы используете @Transactional. В случае простого метода jdbc, вы можете либо использовать чистый jdbc и выполнять обработку транзакций самостоятельно, либо использовать spring-jdbc, который поставляется с менеджером транзакций.
Если вы хотите, чтобы строки базы данных не изменялись в случае выполнения записи, вам необходимо принять во внимание механизмы, связанные с блокировкой строк. - gkatzioura 7 февраля в 15:23
В случае JPA использование @Transactional сделает всю работу. Однако в зависимости от вашего приложения вам может потребоваться блокировка. Проверьте эту статью о блокировке с помощью jpa.
Контроллеры singletons
поэтому они должны быть реализованы потокобезопасным способом.
Создайте свое приложение таким образом, чтобы контроллеры не сохраняли состояния. Добавить поддержку транзакций в вашем @Repository
слой.
Пример:
public class GenericRepository<T, Serializable> {
@Transactional
public void save(T object) {
// save user
}
}
Вы могли бы использовать Spring декларативный механизм управления транзакциями. @Transactional
сама аннотация определяет область действия одной транзакции базы данных.
Ваш контроллер выглядит потокобезопасным. Поскольку нет переменной экземпляра, хранящей состояние. Пользовательский объект будет отличаться для каждого запроса и будет разрешен инфраструктурой MVC.