ithunter
2018-12-05
请教一个问题,业务上有这样的需求,A、B两个用户,如果互相喜欢,则成为好友。设计上是有两张表,一个是like表,一个是friend表,like表有user_id、liker_id两个字段,我设置为复合唯一索引即uk_user_id_liker_id。语句执行顺序是这样的:
以A喜欢B为例:
1、先查询对方有没有喜欢自己(B有没有喜欢A)
select * from like where user_id = B and liker_id = A
2、如果有,则成为好友
insert into friend
3、没有,则只是喜欢关系
insert into like

如果A、B同时喜欢对方,会出现不会成为好友的问题。因为上面第1步,双方都没喜欢对方。第1步即使使用了排他锁也不行,因为记录不存在,行锁无法生效。请问这种情况,在mysql锁层面有没有办法处理

作者回复: 你这个问题很有趣。我想到一个不错的解法。不过我先置顶。让别的同学来回答看看。

好问题,谁有想法po出来。

14
27
评论 14
zc
这是一个写偏序问题,发生的原因是select的时候是并发的,只要查询时带上锁即可破解。
select * from like where (user_id = B and liker_id = A ) or (user_id = A and liker_id = B ) for update
2019-11-29
W
先写like表,然后再判断写不写friend,不开事务,可行不?
2019-11-18
1
nirvana
分两个事务,先写like表,事务提交;再起另一个事务判断是否需要insert friend;
2019-11-07
【芋道源码】
可以考虑去掉 freid 表,然后在 like 表上加个字段,是否相互 like 。
也就是说,如果是 a 和 b 是 fried ,会有一条 a,b 和 b,a 。
2019-10-12
1
nirvana
【芋道源码】
这样貌似不行;同时互相喜欢,可能会有 (a, b, 不互相like) (b, a, 不互相like)的情况;
2019-11-07
Flash
mysql层面不知道有什么好办法没,我觉得可以通过异步消息队列,让喜欢对方的这个请求动作按顺序执行。就可以避免同时喜欢对方时,在数据库层面没有记录的情况。
2019-10-09
飞翔
你这种场景不就是探探这种相亲配对吗,如过互相喜欢就配对成功^_^
2019-09-24
1
Geek_35963d
不要friend表不行吗
2019-09-23
未来怎样
写frient表的前提是必写like表
2019-09-16
alioo
like表增加1列r,值为1表示userid 喜欢 likeid,值为2则相反。在向like表插入时,比较下userid与likeid ascii值大小,ascii值小的始终放到前面,如果发生了userid与likeid交换的情况则列r值为2。
这个样子当同时互相喜欢时,后插入like表的唯一联合主键索引就会提示冲突,插入失败,这个时候将他们插入firend表即可
2019-08-19
3
Geek_a2c349
like表必写,写完再判断是否写friend表
2019-07-05
2