Postgresql 想要实现像多个用户钱包一样可以同时更新,但是x用户钱包一次只能更新一个线程

Postgresql 想要实现像多个用户钱包一样可以同时更新,但是x用户钱包一次只能更新一个线程,postgresql,spring-boot,spring-data-jpa,spring-data,Postgresql,Spring Boot,Spring Data Jpa,Spring Data,我的钱包有一千个用户。我想一次允许多个用户存款和取款,但不允许多个线程一次在同一个用户钱包上存款/取款。 i、 我们想锁定单行对象更新,而不是全表 我使用的是Lower ReentrantLock,但它锁定了整个表,一次只能更新一个用户钱包。因此,更新数千个用户需要很多时间 我们有什么办法可以做到这一点吗 @Component public class BalanceUpdateWorker implements Runnable { public BalanceUpdateWorke

我的钱包有一千个用户。我想一次允许多个用户存款和取款,但不允许多个线程一次在同一个用户钱包上存款/取款。 i、 我们想锁定单行对象更新,而不是全表 我使用的是Lower ReentrantLock,但它锁定了整个表,一次只能更新一个用户钱包。因此,更新数千个用户需要很多时间

我们有什么办法可以做到这一点吗

@Component
public class BalanceUpdateWorker implements Runnable {

    public BalanceUpdateWorker() {
    }

    private Long userId;
    private static ReentrantLock lock = new ReentrantLock();
    private static UserDao userDao;
    BigDecimal depositeAmount;
    BigDecimal withDrawalAmount;
    String comment;
    
    private static WalletTransactionRepository WalletTransactionRepository;

    public BalanceUpdateWorker(Long userId, BigDecimal depositeAmount, BigDecimal withDrawalAmount,String comment) {
        this.userId = userId;
        this.depositeAmount = depositeAmount;
        this.withDrawalAmount = withDrawalAmount;
        this.comment = comment;
    }

    @Autowired
    public void setDao(UserDao userDao) {
        BalanceUpdateWorker.userDao = userDao;
    }

    @Autowired
    public void setTransaction(WalletTransactionRepository WalletTransactionRepository) {
        BalanceUpdateWorker.WalletTransactionRepository = WalletTransactionRepository;
    }

    @Override
    public void run() {
        boolean done = false;
        while (!done) {
            boolean ans = lock.tryLock();
            if (ans) {
                try {
                    Thread.sleep(1500);
                    lock.lock();
                    System.out.println(Thread.currentThread().getId() + "Aquired Lock.");
                    try {
                        Thread.sleep(1500);
                        // logic
                        // update Referral User Wallet
                        if (depositeAmount.compareTo(BigDecimal.ZERO) > 0) {
                            UserEntity userEntity = userDao.findById(Long.valueOf(userId)).get();
                            WalletEntity vwe = userEntity.getWallet();
                            BigDecimal balance = vwe.getBalance();
                            BigDecimal finalBalance = balance.add(depositeAmount);
                            vwe.setBalance(finalBalance);
                            userEntity.setWallet(vwe);
                            userDao.save(userEntity);

                            WalletTransactionEntity entity = new WalletTransactionEntity(
                                    depositeAmount, "DEPOSIT", comment, vwe);
                            WalletTransactionRepository.save(entity);
                            
                        }

                        if (withDrawalAmount.compareTo(BigDecimal.ZERO) > 0) {
                            UserEntity userEntity = userDao.findById(Long.valueOf(21)).get();
                            WalletEntity vwe = userEntity.getWallet();
                            BigDecimal balance = vwe.getBalance();
                            BigDecimal finalBalance = balance.subtract(withDrawalAmount);
                            vwe.setBalance(finalBalance);
                            userEntity.setWallet(vwe);
                            userDao.save(userEntity);
                            WalletTransactionEntity entity = new WalletTransactionEntity(
                                    depositeAmount, "WITHDRAWAL", comment, vwe);
                            WalletTransactionRepository.save(entity);
                        }

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        System.out.println(Thread.currentThread().getId() + "Release  Lock.");
                        lock.unlock();
                    }
                    done = true;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            } else {
                System.out.println(Thread.currentThread().getId() + " waiting for lock");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }