Java - 这是用于预订系统的最佳锁定方法

时间:2014-05-14 20:36:51

标签: java multithreading locking

假设我想为Multiplex创建一个基于Web的预订系统,其中包含2个大厅,每个大厅每天运行4个节目。我想同步每个节目的座位预订。

  • A人试图在A厅预约2PM演出
  • B人试图在A厅预订6PM演出
  • C人试图预留B厅2PM节目
  • D人试图在A厅预约2PM演出
  • E人试图预留B厅的下午6点

在所有这些中,我只希望D人等待A人完成预订,因为他们预留同一个大厅和同一个演出时间。所有其他人应该能够同时预订

我的业务层方法有hallName,showId为参数

public int createBooking(String hallName, int showId){

  //check if there are any available seats
  //access DAO layer to create booking

  return bookingId;
}

我无法同步此方法,因为这会使所有预订都相互等待。

我无法使用信号量,因为它不会根据参数获取/释放锁定。我不得不在获取/释放锁定时传递一个参数,或者根据show id创建一个预订队列。 我不想硬编码锁的数量,因为Hall和节目的数量可能会随着时间的推移而改变。

在Java 6中有办法吗? (框架 - Spring 3 / Server - Websphere7)

可能有一个简单的方法,但我担心我没有考虑正确的方向。

2 个答案:

答案 0 :(得分:1)

你可能会看看事件采购在现实生活中的那种东西。这是一个问题,这是这种架构的一个典型例子。

我不会在这里解释完整的模型,我甚至会背叛它,为了做空:

我会创建BookingRequested事件,具有唯一ID(可能是UUID,或者是数据库提供的)和时间戳,并将它们存储在数据库中(或存储在内存中的队列中)。

然后查询处理器将处理它们。它可能会锁定内存中的对象,或者您甚至可能决定只有一个线程可以在一个房间上工作,从而为这个特定的房间提取未处理的请求。 如果您不能,并且远程系统处理相同的数据,则解决方案可能是乐观锁定。

当决定预订时,这是一个新事件,您也将存储在数据库中。它将包含原始请求的引用和结果。

微软有一本免费的pdf书籍“探索CQRS和事件采购”,有一个非常完整的例子,有一个类似的上下文(一个在不同会议上预订场所的系统)。

答案 1 :(得分:0)

试试这个

public int createBooking(String hallName, int showId){
    synchronized ((hallName + showId).intern()) {
        //check if there are any available seats
        //access DAO layer to create booking
        return bookingId;
    }
}