From 0304fd190e7018dee079cbabdaea94a4cbd9c99d Mon Sep 17 00:00:00 2001 From: Tang Cheng Date: Tue, 21 May 2019 13:03:36 +0800 Subject: [PATCH] =?utf8?q?=E7=BC=96=E5=86=99=E6=96=B0=E4=BA=A4=E6=98=93?= =?utf8?q?=E6=B5=81=E7=A8=8B=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 + .../supwisdom/dlpay/api/dao/AccountDao.java | 4 -- .../api/repositories/TAccountRepository.java | 9 ++- .../api/repositories/TShopaccRepository.java | 7 ++ .../impl/TAccountRepositoryImpl.java | 31 -------- .../com/supwisdom/dlpay/PayApiApplication.kt | 8 +++ .../dlpay/api/repositories/repository_impl.kt | 72 +++++++++++++++++++ .../service/impl/transaction_service_impl.kt | 30 ++++++-- .../dlpay/api/service/transaction_service.kt | 5 ++ 9 files changed, 127 insertions(+), 42 deletions(-) create mode 100644 src/main/java/com/supwisdom/dlpay/api/repositories/TShopaccRepository.java delete mode 100644 src/main/java/com/supwisdom/dlpay/api/repositories/impl/TAccountRepositoryImpl.java create mode 100644 src/main/kotlin/com/supwisdom/dlpay/api/repositories/repository_impl.kt diff --git a/build.gradle b/build.gradle index 350290f9..5af099d3 100644 --- a/build.gradle +++ b/build.gradle @@ -38,6 +38,9 @@ dependencies { implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5' + implementation 'com.github.chenhaiyangs:rpc-tcc-transaction-spring:1.2.0' + implementation 'com.github.chenhaiyangs:rpc-tcc-transaction-api:1.1.0' + implementation 'com.github.chenhaiyangs:rpc-tcc-transaction-core:1.2.0' implementation 'org.postgresql:postgresql:42.2.5' implementation 'com.fasterxml.jackson.module:jackson-module-kotlin' implementation 'com.jcabi:jcabi-manifests:1.1' diff --git a/src/main/java/com/supwisdom/dlpay/api/dao/AccountDao.java b/src/main/java/com/supwisdom/dlpay/api/dao/AccountDao.java index 8d3130db..733a6c2a 100644 --- a/src/main/java/com/supwisdom/dlpay/api/dao/AccountDao.java +++ b/src/main/java/com/supwisdom/dlpay/api/dao/AccountDao.java @@ -34,9 +34,5 @@ public interface AccountDao extends JpaRepository, TAccountRep @Query("select a from TAccount a where a.userid = ?1 and a.subjno=?2") TAccount findByUseridAndSubjno(String userid, String subjno); - @Modifying - @Query("update TAccount t set t.availbal=t.availbal-?3 , t.balance=t.balance-?3 where t.accno=?1 and t.availbal=?2") - int updateAccountBalance(String accno, Double availbal, Double amount); - Page findAllByAccnameContaining(String accname, Pageable pageable); } diff --git a/src/main/java/com/supwisdom/dlpay/api/repositories/TAccountRepository.java b/src/main/java/com/supwisdom/dlpay/api/repositories/TAccountRepository.java index d999a27c..222391f5 100644 --- a/src/main/java/com/supwisdom/dlpay/api/repositories/TAccountRepository.java +++ b/src/main/java/com/supwisdom/dlpay/api/repositories/TAccountRepository.java @@ -1,5 +1,12 @@ package com.supwisdom.dlpay.api.repositories; +import com.supwisdom.dlpay.api.domain.TAccount; +import com.supwisdom.dlpay.api.domain.TPersondtl; + public interface TAccountRepository { - int updateAccountBalance(String accno, Double avaibal, Double amount); + int recalcAccountBalance(String accno, Double avaibal, Double amount, boolean overdraft); + + int recalcAccountBalance(TAccount account, Double amount, boolean overdraft); + + int recalcAccountBalance(TPersondtl dtl, Double amount, boolean overdraft); } diff --git a/src/main/java/com/supwisdom/dlpay/api/repositories/TShopaccRepository.java b/src/main/java/com/supwisdom/dlpay/api/repositories/TShopaccRepository.java new file mode 100644 index 00000000..291bd1c0 --- /dev/null +++ b/src/main/java/com/supwisdom/dlpay/api/repositories/TShopaccRepository.java @@ -0,0 +1,7 @@ +package com.supwisdom.dlpay.api.repositories; + +import com.supwisdom.dlpay.api.domain.TShopdtl; + +public interface TShopaccRepository { + int recalcShopBalance(TShopdtl dtl, Double amount, boolean overdraft); +} diff --git a/src/main/java/com/supwisdom/dlpay/api/repositories/impl/TAccountRepositoryImpl.java b/src/main/java/com/supwisdom/dlpay/api/repositories/impl/TAccountRepositoryImpl.java deleted file mode 100644 index 029e85f5..00000000 --- a/src/main/java/com/supwisdom/dlpay/api/repositories/impl/TAccountRepositoryImpl.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.supwisdom.dlpay.api.repositories.impl; - -import com.supwisdom.dlpay.api.domain.TAccount; -import com.supwisdom.dlpay.api.repositories.TAccountRepository; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -@Repository -@Transactional -public class TAccountRepositoryImpl implements TAccountRepository { - - @PersistenceContext - private EntityManager em; - - @Override - public int updateAccountBalance(String accno, Double avaibal, Double amount) { - - TAccount account = em.find(TAccount.class, accno); - if (account == null) { - return 0; - } - - - - return 0; - } -} diff --git a/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt b/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt index 580ee130..941e6b1f 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt @@ -1,5 +1,6 @@ package com.supwisdom.dlpay +import com.fasterxml.jackson.databind.ser.std.StringSerializer import io.lettuce.core.ReadFrom import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.SpringBootApplication @@ -61,6 +62,13 @@ class HttpSessionConfig { template.setConnectionFactory(connectionFactory) return template } + + @Bean + fun longValueRedisTemplate(connectionFactory: RedisConnectionFactory): RedisTemplate { + val template = RedisTemplate() + template.keySerializer = StringRedisSerializer() + return template + } } diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/repositories/repository_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/repositories/repository_impl.kt new file mode 100644 index 00000000..5c557d3a --- /dev/null +++ b/src/main/kotlin/com/supwisdom/dlpay/api/repositories/repository_impl.kt @@ -0,0 +1,72 @@ +package com.supwisdom.dlpay.api.repositories + +import com.supwisdom.dlpay.api.domain.TAccount +import com.supwisdom.dlpay.api.domain.TPersondtl +import com.supwisdom.dlpay.api.domain.TShopdtl +import com.supwisdom.dlpay.exception.TransactionProcessException +import com.supwisdom.dlpay.framework.domain.TShopacc +import com.supwisdom.dlpay.framework.util.TradeErrorCode +import org.springframework.stereotype.Repository +import org.springframework.transaction.annotation.Transactional +import javax.persistence.EntityManager +import javax.persistence.PersistenceContext + +@Repository +@Transactional +class TAccountRepositoryImpl : TAccountRepository { + + @PersistenceContext + private lateinit var entityManager: EntityManager + + override fun recalcAccountBalance(accno: String, avaibal: Double, amount: Double, overdraft: Boolean): Int { + val account = entityManager.find(TAccount::class.java, accno) ?: return 0 + if (avaibal.compareTo(account.availbal!!) != 0) { + throw TransactionProcessException(TradeErrorCode.ACCOUNT_TRADE_BUSY, + "账户余额已被更新") + } + + //1. 从 redis 读取账户余额 + //2. 没有记录时,读取数据库余额并存入 redis ,如果返回已存在,读取redis 余额 + //3. 扣除 redis 中余额 + val query = entityManager.createQuery("update TAccount a set a.availbal=a.availbal+?1, a.balance=a.balance+?1 " + + "where a.accno=?2 and a.availbal=?3") + ?: throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "更新个人账户余额错误") + + query.setParameter(1, amount) + .setParameter(2, accno) + .setParameter(3, avaibal) + return query.executeUpdate() + } + + override fun recalcAccountBalance(account: TAccount, amount: Double, overdraft: Boolean): Int { + return recalcAccountBalance(account.accno, account.availbal, amount, overdraft) + } + + override fun recalcAccountBalance(dtl: TPersondtl, amount: Double, overdraft: Boolean): Int { + return entityManager.find(TAccount::class.java, dtl.accountNo)?.let { + recalcAccountBalance(it, amount, overdraft) + } ?: throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, + "交易流水<${dtl.refno}>未找到指定个人账户") + } +} + +@Repository +@Transactional +class ShopaccRepositoryImpl : TShopaccRepository { + + @PersistenceContext + private lateinit var entityManager: EntityManager + + override fun recalcShopBalance(dtl: TShopdtl, amount: Double, overdraft: Boolean): Int { + val shopacc = entityManager.find(TShopacc::class.java, dtl.shopaccno) + ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, + "交易流水<${dtl.refno}>商户账户不存在") + + val query = entityManager.createQuery("update TShopacc c set c.balance=c.balance-?1" + + " where c.shopaccno=?2 and c.balance=?3") + query.setParameter(1, amount) + .setParameter(2, dtl.shopaccno) + .setParameter(3, shopacc.balance) + return query.executeUpdate() + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt index 4359f7f3..ebf71181 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt @@ -4,15 +4,26 @@ import com.supwisdom.dlpay.api.TransactionBuilder import com.supwisdom.dlpay.api.TransactionResult import com.supwisdom.dlpay.api.dao.* import com.supwisdom.dlpay.api.domain.* +import com.supwisdom.dlpay.api.repositories.ShopaccRepositoryImpl +import com.supwisdom.dlpay.api.repositories.TAccountRepositoryImpl +import com.supwisdom.dlpay.api.service.PersonAccountService import com.supwisdom.dlpay.api.service.TransactionService import com.supwisdom.dlpay.exception.TransactionProcessException import com.supwisdom.dlpay.framework.util.Subject import com.supwisdom.dlpay.framework.util.TradeDict import com.supwisdom.dlpay.framework.util.TradeErrorCode import org.springframework.beans.factory.annotation.Autowired -import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service import java.sql.SQLException +import javax.transaction.Transactional + + +open class PersonAccountServiceImpl : PersonAccountService { + @Transactional + override fun recalcBalance(account: TAccount, amount: Double) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } +} @Service class TransactionServiceImpl : TransactionService { @@ -39,6 +50,12 @@ class TransactionServiceImpl : TransactionService { @Autowired lateinit var debitCreditDtlDao: DebitCreditDtlDao + @Autowired + lateinit var accountRepository: TAccountRepositoryImpl + + @Autowired + lateinit var shopaccRepository: ShopaccRepositoryImpl + private fun builderRecords(builder: TransactionBuilder, status: String): TransactionResult { // 记录三方的交易流水(个人,商户,科目) try { @@ -250,9 +267,6 @@ class TransactionServiceImpl : TransactionService { transactionMainDao.save(transaction) } - private fun decreseAccountBalance(account: TAccount, amount: Double) { - - } override fun success(refno: String) { val transaction = transactionMainDao.findByRefnoForUpdate(refno) @@ -266,12 +280,16 @@ class TransactionServiceImpl : TransactionService { if (transaction.person) { // update account balance transaction.personDtl?.let { - accoutDao.updateAccountBalance("", 0.0, transaction.personDtl.amount) + accountRepository.recalcAccountBalance(it, it.amount, false) } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, - "个人<${transaction.personDtl.userid}>不存在") + "个人流水<${transaction.refno}>不存在") } if (transaction.shop) { // update shop balance + transaction.shopDtl?.let { + shopaccRepository.recalcShopBalance(it, it.amount, false) + } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, + "商户流水<${transaction.refno}>不存在") } if (transaction.subject) { diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt index b4407c16..8872f33b 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt @@ -2,6 +2,7 @@ package com.supwisdom.dlpay.api.service import com.supwisdom.dlpay.api.TransactionBuilder import com.supwisdom.dlpay.api.TransactionResult +import com.supwisdom.dlpay.api.domain.TAccount import org.springframework.transaction.annotation.Propagation import org.springframework.transaction.annotation.Transactional @@ -20,4 +21,8 @@ interface TransactionService { @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class]) fun success(refno: String) +} + +interface PersonAccountService { + fun recalcBalance(account: TAccount, amount: Double) } \ No newline at end of file -- 2.17.1