我找到了几个资源来帮助我解决这个问题,但我似乎无法将所有成分混合在一起以满足我的需求。
我想"锁定"一个Cat
(甚至几个)被其他用户宠爱,如果其中(或它们)的宠物已经在进行中。我还想向呼叫者提供反馈,告诉他谁在他面前调用了API。
@Local
@Singleton // or @Stateful?
public class CatPetterBean_Local implements CatBean_Facade
{
/**
* Key - The ID of the Cat
*/
final private ConcurrentHashMap<Integer, User> pettingState = new ConcurrentHashMap<>();
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Override
public GzipROWithMsg<Object> pet(final ImmutableSet<Integer> catIds)
{
checkIfTheyAreBeingPetted_AndThrowRuntimeExec(catIds);
<...>
// After petting, they will be saved by the caller bean (e.g. CatPetterBeanImpl)
}
<...>
}
Cat
在数据库中保留一个州:ALREADY_PETTED
和NOT_PETTED
。一旦它已经拍了,它就不能再被宠爱了。我甚至想过从数据库中加载Cat
并在运行中检查其状态,但我认为它的网络流量更多。synchronized
关键字,@Lock
注释等概念答案 0 :(得分:0)
EJB Singletons有一个锁定机制,默认情况下,所有bean方法都是通过写锁序列化的。 EJB Singletons上的默认并发模型是:@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER),这是默认值,不需要使用它来注释单例。正如我之前所说的那样,当每个方法都被写入锁定时,就会发生容器并发管理。如果你想更好地控制单例方法你可以使用@Lock(LockType.READ)注释它们,这意味着可以同时访问该方法,而没有人在bean上持有写锁,或者@Lock(LockType.WRITE)给予独占访问当前线程。
或者,您可以使用Bean并发管理。在这种情况下,您应该使用以下命令注释您的单例类:@ConcurrencyManagement(ConcurrencyManagementType.BEAN)。 在这种情况下,您使用同步和其他Java并发的好东西。对于我的大部分需求,容器管理的并发性已经足够了。
对上述代码片段的另一个评论是@Local似乎不合适,我的猜测是CatBean_Facade应该用@Local注释。