阻止REST客户端使用相同的参数同时执行相同的方法

时间:2017-04-03 09:12:03

标签: java spring rest api spring-mvc

考虑Spring MVC java web-application,它提供了一些REST API

我们说它有很多方法,其中一个方法是DELETE /api/foo/{id},显然会从给定foo的数据库中删除id实体。

问题是由于数据库中的大数据,此操作不是立即的,因此如果客户端尝试在同一实体上同时执行多次删除操作,请说

DELETE /api/foo/123 x次(当然在客户端软件中出错),

它会在数据库中造成一些令人不快的副作用(你知道,如果你尝试在几个交易中删除相同的实体,那通常不太好)。

我的问题是:Spring MVC中防止此类情况的最佳做法是什么?

我当然可以在每个此类更新方法(Foo)中引入PUT/DELETE id的同步。我需要为所有实体和所有PUT/DELETE API方法执行此操作,但我真的不想这样做。我想它应该是一些优雅而好的解决方案,如何在拦截器/ servlet级别上执行这种类型的同步,即不在控制器级别的服务上。

我还可以创建特定的拦截器并在那里等待重复的请求(具有相同URL和参数的请求)。但同样,它听起来并不是一个优雅的解决方案(直到我确保无法以更美的方式在Spring MVC中进行配置)。

1 个答案:

答案 0 :(得分:1)

这是一个并发问题,应该通过使用适当的事务和锁定级别来处理。不幸的是,这里没有任何单一尺寸可供选择,根据您的实际需求,您可能必须实施乐观或悲观锁定,以及可能的事务级别之一(从无交易到可序列化事务)。

一般来说,在网络级别处理这些问题是一个坏主意,因为你会在请求中做什么等问题想要删除另一个同时显示的数据?在SpringMVC中,常见的方法是在服务层中使用事务方法。另外,您应该在持久层中声明一个乐观或悲观的锁定系统。

乐观层通常会提供更高的吞吐量,代价是以异常结束的某些事务。在这种情况下,目前的最佳做法是向用户报告问题,要求他/她再次发送他/她的请求。