请问湿胸,Spring Data JPA如何处理事务?如何加入锁机制?多线程事务是否会无效?

来源:4-10 订单服务service

PhiloChou

2018-05-17

湿胸你好,今天我测试了一下Data-JPA,想测试一下锁,比如用户注册,当邮箱不存在时,添加数据库。

Repository层

```

public interface UserRepository extends JpaRepository<User, Integer> {

    @Lock(LockModeType.PESSIMISTIC_WRITE)

    Optional<User> findByEmail(String email);

}

```

Service层

```

@Transactional

public User signup(String email, String password) {

    Optional<User> userExists = userRepository.findByEmail(email);


    try {

        Thread.sleep(1000);

    } catch (InterruptedException e) {

        e.printStackTrace();

    }

    if (!userExists.isPresent()) {

        User user = new User();

        user.setEmail(email);

        user.setPassword(password);

         return userRepository.save(user);

    }        

```


UnitTest

```

@Test

public void signupTest() {

    ExecutorService pool = Executors.newFixedThreadPool(2);

    pool.execute(() -> {

        User user = userService.signup("123", "123");

        if (user != null) {

            log.info("用户注册成功");

        }

    });


    

pool.execute(() -> {

        User user = userService.signup("123", "123");

        if (user != null) {

            log.info("用户注册成功");

        }

    });

    // 这里加上个10秒的sleep

}

```

数据库仍然会插入两条数据。

写回答

1回答

廖师兄

2018-05-18

锁不是用在这样的场景。。。你这种情况,Mysql给email字段加唯一约束。

关于数据库的锁,推荐你看看 https://www.cnkirito.moe/%E4%BD%BF%E7%94%A8JPA%E5%AE%9E%E7%8E%B0%E4%B9%90%E8%A7%82%E9%94%81/

然后你再去搜搜为什么要用锁,是在什么场景下用。


0
1
PhiloChou
感谢师兄百忙中的回复。我补充一下场景。假设一种情况,用户可以用Email或者Phone注册,意味着数据库中这两个字段可为NULL,也就是DB中,这两个字段均不采用唯一约束(当然,可以考虑这两个字段的复合唯一索引)。由此引出在注册过程中,锁表的意图。目前我测试,当采用SERIALIZABLE的隔离级别时,一定可以解决这一问题。但除此之外,还有没有更好的思路去解决类似问题?再次麻烦师兄解答。
2018-05-18
共1条回复

SpringCloud Finchley(M2+RELEASE+SR2)微服务实战

SpringCloud组件实现微服务,【已升级Finchley.Release】

5668 学习 · 2489 问题

查看课程