我有一个看起来像这样的域对象:
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同步的想法可能会获得更好的性能。不会以一种或另一种方式猜测,但建议您以两种方式进行评估(如果您愿意永远赌一把,那就是永远不要从多个客户端节点获取更新,即-)。
`