ReentrantLock锁不起作用


插入数据之前需要先检查数据库中没有了才插入,没加锁之前发现如果两次添加请求很接近会出现重复插入情况,所以添加了一个ReentrantLock锁,但是实际使用发现还是会出现重复插入。
锁添加在Spring 的 Controller 里:


 @RestController
@RequestMapping("/user")
public class UserAction {
    Lock lock = new ReentrantLock();

    @RequestMapping(value = "add", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public ResponseEntity addUser(User user) {
        lock.lock();
        try {
            //检查数据库是否已有用户 没有的话才加入
            //代码略
        } finally {
            lock.unlock();
        }
    }

java mysql lock

春哥信徒A 9 years, 3 months ago

没用过spring mvc,不过你的action每次是不是一个新的实例?如果是的话那每个请求的lock是不同的,有怎会生效,所以每次打印下lock的hashcode看看是不是同一个对象,不是的话加个static吧

sonei answered 9 years, 3 months ago

是不是集群部署?两次请求落在了不同的机器上?
java程序级别的锁是没办法约束集群的情况的;
最终的可靠方案还是需要唯一性主键约束以及设置数据库的事务隔离级别

update:
也有可能是UserAction这个类不是单例,你看看spring mvc是否每次请求都会重新创建一个UserAction实例,这样会导致Lock也被重新创建,那么多个请求使用的其实不是同一个lock,这样就看上去没用了;

可以考虑把这个Lock放在一个更全局的地方

悲剧的柔柔姐 answered 9 years, 3 months ago

Your Answer