Postgresql 想要实现像多个用户钱包一样可以同时更新,但是x用户钱包一次只能更新一个线程
我的钱包有一千个用户。我想一次允许多个用户存款和取款,但不允许多个线程一次在同一个用户钱包上存款/取款。 i、 我们想锁定单行对象更新,而不是全表 我使用的是Lower ReentrantLock,但它锁定了整个表,一次只能更新一个用户钱包。因此,更新数千个用户需要很多时间 我们有什么办法可以做到这一点吗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
@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();
}
}
}
}