我想这篇应该也不会从百度被检索过来吧,毕竟我没有把场景当标题、
场景是这样的,也很常见。
我有一张用户表,大致内容是这样的:
在用户登录的时候,我需要事先判定此用户是否已在线,若不在线,登录之后需要修改为在线状态。
这对于我来说需要两条SQL语句才能解决,有些专业的SQL大佬应该是可以用一条解决吧,毕竟我不是专业写SQL的。
单用户是没什么问题的,但是我用线程池来登录的时候问题就出来了,第一个线程还没 update,第二个、第三个、第四个···线程就开始select 了。 那这时候怎么办呐?
今天就这个问题,我在网上看到的最逗比的一个“回答”就是:怎么会存在两个线程同时登录这种现象? 原谅他的无知哈。
以前老师教我们的时候,是直接让我们在业务代码里面对数据库操作加锁,其实我一直就很纳闷儿,人家自己有锁,为什么要我们来加?加一下直接串行了,那我五百个不同账号的用户也一个一个登录?数据库明明有行锁,用来生锈吗?
网上更多的人就是千篇一律的答案:用 select ··· for update,然后拿出一坨的代码根本就没法看。也没个运行印证,估计自己都没去跑一下。我还拿着他们的代码去试了,没什么用。大体如下:
mysql -uroot -p
use database_name
start transaction;
select ··· for update;
mysql -uroot -p
use database_name
start transaction;
select ···
结果就是怎么查怎么有数据,怎么查怎么有反馈。
然后他们就跳过了这一步,直接说:“看,update 的时候会被锁住吧,没骗你吧!”
最后经过我多番摸索得出结论:
1、需要打开事务、 2、需要用 for update 进入读写锁环境 3、需要所有需要互斥的任务都进入读写锁环境
就是说,所有相关事务都需要 for update,否则就是可以查询的
|