🎨 交易功能代码优化
This commit is contained in:
parent
f1a739e73b
commit
c2651d0ad4
@ -6,7 +6,8 @@ package com.rymcu.forest.enumerate;
|
||||
public enum TransactionCode {
|
||||
|
||||
INSUFFICIENT_BALANCE(901, "余额不足"),
|
||||
UNKNOWN_ACCOUNT(902, "账号不存在");
|
||||
UNKNOWN_ACCOUNT(902, "账号不存在"),
|
||||
FAIL(903, "交易失败");
|
||||
|
||||
private int code;
|
||||
|
||||
|
@ -16,11 +16,10 @@ public interface TransactionRecordMapper extends Mapper<TransactionRecord> {
|
||||
* 交易
|
||||
*
|
||||
* @param formBankAccount
|
||||
* @param toBankAccount
|
||||
* @param money
|
||||
* @return
|
||||
*/
|
||||
Integer transfer(@Param("formBankAccount") String formBankAccount, @Param("toBankAccount") String toBankAccount, @Param("money") BigDecimal money);
|
||||
Integer debit(@Param("formBankAccount") String formBankAccount, @Param("money") BigDecimal money);
|
||||
|
||||
/**
|
||||
* 查询指定账户的交易记录
|
||||
@ -48,4 +47,11 @@ public interface TransactionRecordMapper extends Mapper<TransactionRecord> {
|
||||
* @return
|
||||
*/
|
||||
Boolean existsWithNewbieRewards(@Param("bankAccount") String bankAccount);
|
||||
|
||||
/**
|
||||
* @param toBankAccount
|
||||
* @param money
|
||||
* @return
|
||||
*/
|
||||
Integer credit(@Param("toBankAccount") String toBankAccount, @Param("money") BigDecimal money);
|
||||
}
|
||||
|
@ -18,40 +18,62 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* @author ronger
|
||||
*/
|
||||
@Service
|
||||
public class TransactionRecordServiceImpl extends AbstractService<TransactionRecord> implements TransactionRecordService {
|
||||
|
||||
@Resource
|
||||
private TransactionRecordMapper transactionRecordMapper;
|
||||
@Resource
|
||||
private BankAccountMapper bankAccountMapper;
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
private final Map<String, ReentrantLock> userTransferLocks = new HashMap<>();
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public TransactionRecord transfer(TransactionRecord transactionRecord) {
|
||||
// 判断发起者账户状态
|
||||
boolean formAccountStatus = checkFormAccountStatus(transactionRecord.getFormBankAccount(), transactionRecord.getMoney());
|
||||
if (formAccountStatus) {
|
||||
Integer result = transactionRecordMapper.transfer(transactionRecord.getFormBankAccount(), transactionRecord.getToBankAccount(), transactionRecord.getMoney());
|
||||
if (result > 0) {
|
||||
transactionRecord.setTransactionNo(nextTransactionNo());
|
||||
transactionRecord.setTransactionTime(new Date());
|
||||
transactionRecordMapper.insertSelective(transactionRecord);
|
||||
ReentrantLock lock = getUserTransferLocks(transactionRecord.getFormBankAccount());
|
||||
lock.lock();
|
||||
try {
|
||||
// 判断发起者账户状态
|
||||
boolean formAccountStatus = checkFormAccountStatus(transactionRecord.getFormBankAccount(), transactionRecord.getMoney());
|
||||
boolean toAccountStatus = checkFormAccountStatus(transactionRecord.getToBankAccount(), BigDecimal.valueOf(0));
|
||||
if (formAccountStatus && toAccountStatus) {
|
||||
Integer result = transactionRecordMapper.debit(transactionRecord.getFormBankAccount(), transactionRecord.getMoney());
|
||||
if (result > 0) {
|
||||
result = transactionRecordMapper.credit(transactionRecord.getToBankAccount(), transactionRecord.getMoney());
|
||||
if (result > 0) {
|
||||
transactionRecord.setTransactionNo(nextTransactionNo());
|
||||
transactionRecord.setTransactionTime(new Date());
|
||||
transactionRecordMapper.insertSelective(transactionRecord);
|
||||
return transactionRecord;
|
||||
}
|
||||
}
|
||||
} else if (toAccountStatus) {
|
||||
throw new TransactionException(TransactionCode.INSUFFICIENT_BALANCE);
|
||||
} else {
|
||||
throw new TransactionException(TransactionCode.UNKNOWN_ACCOUNT);
|
||||
}
|
||||
} else {
|
||||
throw new TransactionException(TransactionCode.INSUFFICIENT_BALANCE);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
throw new TransactionException(TransactionCode.FAIL);
|
||||
}
|
||||
|
||||
private ReentrantLock getUserTransferLocks(String formBankAccount) {
|
||||
synchronized (userTransferLocks) {
|
||||
ReentrantLock lock = userTransferLocks.get(formBankAccount);
|
||||
if (lock == null) {
|
||||
lock = new ReentrantLock();
|
||||
userTransferLocks.put(formBankAccount, lock);
|
||||
}
|
||||
return lock;
|
||||
}
|
||||
return transactionRecord;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -162,7 +184,7 @@ public class TransactionRecordServiceImpl extends AbstractService<TransactionRec
|
||||
private boolean checkFormAccountStatus(String formBankAccount, BigDecimal money) {
|
||||
BankAccount bankAccount = findInfoByBankAccount(formBankAccount);
|
||||
if (Objects.nonNull(bankAccount)) {
|
||||
return bankAccount.getAccountBalance().compareTo(money) > 0;
|
||||
return bankAccount.getAccountBalance().compareTo(money) >= 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -11,13 +11,15 @@
|
||||
<result column="transaction_type" property="transactionType"></result>
|
||||
<result column="transaction_time" property="transactionTime"></result>
|
||||
</resultMap>
|
||||
<update id="transfer">
|
||||
<update id="debit">
|
||||
update forest_bank_account
|
||||
set account_balance = account_balance - #{money}
|
||||
where bank_account = #{formBankAccount};
|
||||
where bank_account = #{formBankAccount} and account_balance >= #{money}
|
||||
</update>
|
||||
<update id="credit">
|
||||
update forest_bank_account
|
||||
set account_balance = account_balance + #{money}
|
||||
where bank_account = #{toBankAccount};
|
||||
where bank_account = #{toBankAccount}
|
||||
</update>
|
||||
<select id="selectTransactionRecords" resultMap="DTOResultMap">
|
||||
select *
|
||||
|
Loading…
Reference in New Issue
Block a user