我们有一个使用Spring Boot,JPA和Hibernate构建的REST API。使用API的客户端对网络的访问不可靠。为了避免给最终用户带来太多错误,我们使客户端重试不成功的请求(例如,发生超时后)。
由于我们无法确定再次发送请求时服务器尚未处理该请求,因此我们需要使POST请求成为幂等。也就是说,发送两次相同的POST请求一定不能两次创建相同的资源。
为此,我做了以下工作:
到目前为止,一切都很好。
我在同一数据库上有多个服务器实例,并且请求是负载平衡的。结果,任何实例都可以处理请求。
在我当前的实现中,可能会发生以下情况:
在这种情况下,该请求已被处理两次,这是我要避免的事情。
我想到了两种可能的解决方案:
我正在使用Filter
来检索和存储响应。我的过滤器大致如下所示:
@Component
public class IdempotentRequestFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String requestId = getRequestId(request);
if(requestId != null) {
ResponseCache existingResponse = getExistingResponse(requestId);
if(existingResponse != null) {
serveExistingResponse(response, existingResponse);
}
else {
filterChain.doFilter(request, response);
try {
saveResponse(requestId, response);
serve(response);
}
catch (DataIntegrityViolationException …
Run Code Online (Sandbox Code Playgroud)