Java Spring+Hibernate+Redis的分布式锁

Java Spring+Hibernate+Redis的分布式锁,java,spring,multithreading,hibernate,locking,Java,Spring,Multithreading,Hibernate,Locking,我一直在使用SpringMVC+Hibernate和redis开发一个多线程web应用程序,用于缓存存储。我正在寻找一种将锁应用于控制器或服务的方法 我不能使用Hibernate提供的锁定机制,因为它是在数据库级别应用的 下面是一个例子: @RestController @RequestMapping(RestConstants.BASE_PATH + "/campaigns") Class CampaignController { @RequestMapping(value = "

我一直在使用SpringMVC+Hibernate和redis开发一个多线程web应用程序,用于缓存存储。我正在寻找一种将锁应用于控制器或服务的方法

我不能使用Hibernate提供的锁定机制,因为它是在数据库级别应用的

下面是一个例子:

@RestController
@RequestMapping(RestConstants.BASE_PATH + "/campaigns")
Class CampaignController  {

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public ApiResponse<?> findOne(@PathVariable Integer id) {
        Campaign campaign = repo.findOne(id);
        return toResponse(campaign);
    }

    @RequestMapping(value = "", method = RequestMethod.POST)
    public create(@RequestBody Campaign campaign) {
        //create an campaign here
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.PATCH)
    public update(@RequestBody Campaign campaign) {
        //update an campaign here
    }
}

@RestController
@RequestMapping(RestConstants.BASE_PATH + "/bulkCampaigns")
Class CampaignBulkController {
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public create(@RequestPart MultipartFile data) {
        /* 
        Data contains a list of campaigns with their details, 
         controller will iterate through the list and create all the campaigns.

         */
    }
}
在处理映射到CampaignBulkController中创建方法的请求时,无法处理对活动的所有其他写入,但允许读取。也就是说,应该删除更新或创建活动/活动的请求

有多个服务器,每个服务器都是多线程的


我是春天和冬眠的新手,任何想法或建议都将不胜感激

我将在这里概述一个初步答案,可能供以后修改

如果对常规操作使用共享锁和读锁,则可以让特权操作使用写锁来阻止常规操作

// Regular operation tries to lock, if not successful a privileged operation is happening
if(!lock.readLock().tryLock())
    return cannotProcessResponse;

performRegularOperation();
lock.readLock().unlock();

现在这种方法存在一些问题。如果使用单个共享锁,一次只能运行一个特权操作。如果这是一个问题,那么可以使用多个锁,并且它们的读锁锁定在一起,这很容易出现死锁,因此必须小心。还应考虑锁的公平性。

根据您的描述,听起来数据库级别正是您想要的锁所在?锁定一个表,其他服务必须等待该表解锁后才能使用。有两件事使其略有不同:1当特殊请求正在处理时,其他请求应被删除,并且用户收到一条消息,如“无法在处理中处理您的请求”,请稍后再试。2我需要确保当请求传入时,只有在处理特殊请求时才会删除该请求。特殊请求是否与非特殊请求共享表?特殊请求是特定的操作,还是常规操作,但有一些特殊的标志表明它们需要区别对待?您应该编辑您的问题,并提供一些关于您可以拥有何种用例的示例。@Kayaman我刚刚更新了我的问题,如果您需要更多详细信息,请告诉我。谢谢!我刚刚更新了我的问题,这样多个特权操作也不能同时运行。您建议如何实现锁?这样会更简单。只需使用一个共享锁,例如,将其作为bean注入,然后按照我在回答中概述的操作。当然,在盲目复制我的代码之前,你要做大量的阅读。bean线程安全吗?我可以在多个线程和多个web服务器实例中只声明一个bean吗?您没有提到您有多个服务器。然后,您必须获得某种类型的外部锁定提供程序。您还需要学习更多关于Spring的知识,因为bean线程安全没有多大意义
// Privileged operation always waits for lock
lock.writeLock().lock();
performPrivilegedOperation();
lock.writeLock().unlock();