如何在弹簧启动中使用线程安全控制器

我该如何创建一个线程安全的控制器?

根据最佳实践,控制器是单身人士。

考虑下面的代码,其中我通过自动assembly的服务对象存储用户数据,这使我的代码有状态。 我如何使下面的代码线程安全。

@RestController class ApiController { @Autowired IDbService iDBService; @RequestMapping(value = "/api/adduser", method = RequestMethod.POST) public ResponseEntity createUser(@RequestBody User user){ User savedUser=iDBService.create(user); return new ResponseEntity(savedUser, HttpStatus.CREATED); } 

这是我的服务实现。 我在我的服务中共享变量

 public class IDbServiceImpl implements IDBService{ @Autowired GenericRepository genericRepository; @Override public T create(T object) { return genericRepository.save(object); } 

}

默认情况下,您的控制器是单件,默认情况下您的服务也是单件。

因此,为了使它们的线程安全,您必须确保在服务内部发生的操作必须是线程安全的,以防更改服务内对象的状态,即。 一个列表。

如果使用rdbms,那么您就遇到了与事务相关的问题。

如果您使用spring和Jpa,则事务管理器会在您使用@Transactional的情况下处理您的更新。 在普通的jdbc方法的情况下,您可以使用纯jdbc并自己进行事务处理或使用事务管理器附带的spring-jdbc。

如果您希望在正在进行写入时不更改数据库行,则必须考虑与行锁定相关的机制。 – gkatzioura 2月7日15:23

如果JPA使用@Transactional将完成工作。 但是,根据您的应用程序,您可能需要考虑锁定。 查看有关使用jpa锁定的文章。

你的控制器看起来线程安全 因为没有存储状态的实例变量。 每个请求的用户对象都不同,将由MVC框架解析。

控制器是singletons ,因此它们应该以线程安全的方式实现。

以控制器无状态的方式设计应用程序。 在@Repository层添加事务支持。

例:

 public class GenericRepository { @Transactional public void save(T object) { // save user } } 

您可以使用Spring声明式事务管理机制。 @Transactional注释本身定义了单个数据库事务的范围。