Java事务和redis锁使用注意事项

Java事务和redis锁使用注意事项_第1张图片

如图中所示,register方法开启了事务,方法里面用到了redis锁,当执行完成后锁释放,事务提交。

在这个过程看似没有什么毛病,但是在高并发场景下就会暴露出问题。
请求A,B是同一个手机号来注册,A请求首先得到redis锁,B请求等待redis当A请求处理完成,
A请求会先判断手机号是否存在(我们默认是没有注册过得手机号,所以是不存在,可以注册的,会将手机号落库)
然后释放锁后。B请求可以拿到redis锁,但是此时A请求得事务可能还有提交成功(可以理解为正在提交,
因为提交也是需要时间,可能这个时间很短)。mysql事务默认是可重复读,A事务和B事务是相互隔离的,A事务中
的改动,在B事务中是看不到的,所以此时B在A请求的事务还没有提高成功时去查数据库是没有这个手机号的,
所以B请求也可以正常执行,并且也会在数据库中插入一条该手机号记录。
此时A,B请求完成后,数据库会出现两条手机号一样得数据,这就出问题了。

那么该如何避免这种不好的情况发生呢?
①数据库注册表对手机号建立唯一索引(治标不治本)
②先提交事务,再释放锁(这种应该是比较好得方法)

你可能感兴趣的:(java,事务,redis锁)