我有一个看起来像这样的域对象:

class UserStuff
{
    String userid;
    boolean primordial;
}


在表中,primordial是TINYINT。一个用户可能有许多UserStuff。我要确保的是,只有一行(创建的第一行)将具有primordial ==1。所有后续行将具有primordial ==0。乍一看,无需担心。假设可能同时发生多个UserStuff的创建请求,如何保证此约束?

我最初的想法是在字符串上同步(在域服务中)

class DomainService
{
    public void create( UserStuff stuff )
    {
        synchronized( stuff.userid + "/userstuff/lock" )
        {
            ...

        }
    }
}


我希望听到有关此方法和替代方法的评论。谢谢

最佳答案

一般来说,SQL方法是使(userid, primordial)成为唯一的复合键,并且将INSERT语句与ON DUPLICATE KEY UPDATE子句一起使用-否则会设置primordial(但是我承认我不是)请确保如果UPDATE也遇到重复,会发生什么情况,就像插入第二个非原始UserStuff时一样。

另外,对于适当隔离的事务,您可以首先SELECT检查是否已经存在userid,然后在同一事务INSERT中使用适当的primordial值进行检查。

如果您曾经从多个进程(可能在不同的客户端节点上)进行过更新,则SQL方法将更加可靠,但是,如果您100%确定这种情况永远不会发生,则基于Java同步的想法可能会获得更好的性能。不会以一种或另一种方式猜测,但建议您以两种方式进行评估(如果您愿意永远赌一把,那就是永远不要从多个客户端节点获取更新,即-)。

`

10-02 10:11