增加了商户余额异步更新机制
diff --git a/src/main/java/com/supwisdom/dlpay/api/dao/ShopdtlDao.java b/src/main/java/com/supwisdom/dlpay/api/dao/ShopdtlDao.java
index 611d3cb..0e49580 100644
--- a/src/main/java/com/supwisdom/dlpay/api/dao/ShopdtlDao.java
+++ b/src/main/java/com/supwisdom/dlpay/api/dao/ShopdtlDao.java
@@ -7,9 +7,13 @@
import org.springframework.stereotype.Repository;
import javax.persistence.LockModeType;
+import java.util.List;
@Repository
public interface ShopdtlDao extends JpaRepository<TShopdtl, String>, JpaSpecificationExecutor<TShopdtl> {
@Lock(LockModeType.OPTIMISTIC)
TShopdtl findTShopdtlByRefno(String refno);
+
+ @Lock(LockModeType.OPTIMISTIC)
+ List<TShopdtl> findAllByStatusAndUpdateBala(String status, Boolean flag);
}
diff --git a/src/main/java/com/supwisdom/dlpay/api/repositories/ShopaccService.java b/src/main/java/com/supwisdom/dlpay/api/repositories/ShopaccService.java
index cea6e08..2d8ebcf 100644
--- a/src/main/java/com/supwisdom/dlpay/api/repositories/ShopaccService.java
+++ b/src/main/java/com/supwisdom/dlpay/api/repositories/ShopaccService.java
@@ -4,7 +4,15 @@
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
+import java.util.List;
+
public interface ShopaccService {
@Transactional(isolation = Isolation.READ_COMMITTED)
void recalcShopBalance(TShopdtl dtl, Double amount, boolean overdraft);
+
+ @Transactional(isolation = Isolation.READ_COMMITTED)
+ void recalcShopBalance(String refno, boolean overdraft);
+
+ @Transactional
+ List<TShopdtl> findUnupdatedShopDtl(int maxCount);
}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/domain/TShopacc.java b/src/main/java/com/supwisdom/dlpay/framework/domain/TShopacc.java
index 9d8b8b4..b7df8d2 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/domain/TShopacc.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/domain/TShopacc.java
@@ -1,9 +1,6 @@
package com.supwisdom.dlpay.framework.domain;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
import java.sql.Timestamp;
@Entity
@@ -34,9 +31,7 @@
@Column(name = "BALANCE", length = 15, precision = 2)
private Double balance = 0.0;
- @Column(name = "VERSION")
- private Long version = 1L;
-
+ @Version
@Column(name = "LASTUPDATE")
private Timestamp lastUpdate = new Timestamp(System.currentTimeMillis());
@@ -107,10 +102,6 @@
return balance;
}
- public Long getVersion() {
- return this.version;
- }
-
public String getMac() {
return mac;
}
@@ -122,7 +113,6 @@
public void incrOrDecrBalance(Double amount) {
this.balance += amount;
this.lastUpdate = new Timestamp(System.currentTimeMillis());
- this.version++;
}
}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java b/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
index 71df139..08bf26f 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
@@ -36,6 +36,11 @@
public static final int TRANSACTION_IS_FINISHED = 10005;
/**
+ * 交易状态错误,正在处理
+ */
+ public static final int TRANSACTION_HAS_BEEN_PROCESS = 100030;
+
+ /**
* 交易已冲正
*/
public static final int TRANSACTION_HAS_CANCELED = 10006;
diff --git a/src/main/kotlin/com/supwisdom/dlpay/account_process_async.kt b/src/main/kotlin/com/supwisdom/dlpay/account_process_async.kt
index a1bd2f0..3e3918f 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/account_process_async.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/account_process_async.kt
@@ -13,6 +13,8 @@
import org.springframework.scheduling.annotation.EnableAsync
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
import org.springframework.stereotype.Component
+import org.springframework.stereotype.Service
+import org.springframework.transaction.annotation.Transactional
import java.lang.reflect.Method
import java.util.concurrent.Executor
@@ -46,25 +48,11 @@
private val logger = KotlinLogging.logger { }
@Autowired
- private lateinit var transactionMainDao: TransactionMainDao
-
- @Autowired
- lateinit var shopdltDao: ShopdtlDao
-
- @Autowired
private lateinit var shopaccService: ShopaccService
@Async("shopAccBalanceUpdater")
+ @Transactional
fun updateShopBalance(shopdtlRefno: String) {
- shopdltDao.findTShopdtlByRefno(shopdtlRefno)?.also {
- if (it.updateBala) {
- logger.warn { "shop balance update refno <$shopdtlRefno> has been updated" }
- return
- }
- }?.also {
- shopaccService.recalcShopBalance(it, it.amount, true)
- it.updateBala = true
- shopdltDao.save(it)
- } ?: logger.warn { "shop balance updater refno<$shopdtlRefno> not found" }
+ shopaccService.recalcShopBalance(shopdtlRefno, true)
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
index 1214889..12cb97d 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
@@ -7,10 +7,7 @@
import com.supwisdom.dlpay.api.bean.*
import com.supwisdom.dlpay.api.dao.TransactionMainDao
import com.supwisdom.dlpay.api.domain.TAccount
-import com.supwisdom.dlpay.api.service.AccountUtilServcie
-import com.supwisdom.dlpay.api.service.ConsumePayService
-import com.supwisdom.dlpay.api.service.TransactionService
-import com.supwisdom.dlpay.api.service.UserService
+import com.supwisdom.dlpay.api.service.*
import com.supwisdom.dlpay.exception.RequestParamCheckException
import com.supwisdom.dlpay.exception.TransactionCheckException
import com.supwisdom.dlpay.exception.TransactionException
@@ -47,10 +44,7 @@
lateinit var transactionMainDao: TransactionMainDao
@Autowired
- lateinit var transactionService: TransactionService
-
- @Autowired
- private lateinit var shopAccBalanceAsyncTask: ShopAccBalanceAsyncTask
+ lateinit var transactionService: TransactionServiceProxy
/**
* 流水结果查询统一接口
@@ -181,7 +175,7 @@
}
}.init(transactionService)
- transactionService.success(dtl.refno, "")
+ transactionService.success(dtl.refno)
return ResponseEntity.ok(ResponseBodyBuilder.create()
.data("refno", dtl.refno)
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_task.kt b/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_task.kt
new file mode 100644
index 0000000..a0379df
--- /dev/null
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_task.kt
@@ -0,0 +1,27 @@
+package com.supwisdom.dlpay.api
+
+import com.supwisdom.dlpay.api.dao.ShopdtlDao
+import com.supwisdom.dlpay.api.domain.TShopdtl
+import com.supwisdom.dlpay.api.repositories.ShopaccService
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.scheduling.annotation.Scheduled
+import org.springframework.stereotype.Service
+import org.springframework.transaction.annotation.Transactional
+
+@Service
+class MySchedulerTask {
+ @Autowired
+ private lateinit var shopaccService: ShopaccService
+
+ fun doShopBlanceUpdate(dtl: TShopdtl) {
+ shopaccService.recalcShopBalance(dtl.refno, true)
+ }
+
+ @Scheduled(fixedRate = 5000)
+ @Transactional
+ fun dealShopUnupdatedDtl() {
+ shopaccService.findUnupdatedShopDtl(100).forEach {
+ doShopBlanceUpdate(it)
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt
index b7b4604..6e72082 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt
@@ -8,6 +8,7 @@
import com.supwisdom.dlpay.framework.service.SystemUtilService
import com.supwisdom.dlpay.framework.util.DateUtil
import com.supwisdom.dlpay.framework.util.TradeDict
+import com.supwisdom.dlpay.framework.util.TradeDict.*
import com.supwisdom.dlpay.framework.util.TradeErrorCode
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Repository
@@ -68,7 +69,7 @@
account.lastdayTransamt = 0.0
account.lastdayDpsamt = 0.0
}
- if (dtl.tradeflag == TradeDict.TRADE_FLAG_OUT) {
+ if (dtl.tradeflag == TRADE_FLAG_OUT) {
account.lastdayTransamt += amount
} else {
account.lastdayDpsamt += amount
@@ -93,14 +94,32 @@
override fun recalcShopBalance(dtl: TShopdtl, amount: Double, overdraft: Boolean) {
val shopacc = entityManager.find(TShopacc::class.java, dtl.shopaccno, LockModeType.OPTIMISTIC)
?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS,
- "交易流水<${dtl.refno}>商户账户不存在")
+ "商户账户<${dtl.shopaccno}>不存在")
shopacc.balance += amount
if (shopacc.balance < 0.0 && !overdraft) {
throw TransactionProcessException(TradeErrorCode.SHORT_BALANCE_ERROR,
"商户账户余额不足")
}
-
entityManager.persist(shopacc)
}
+
+ override fun recalcShopBalance(refno: String, overdraft: Boolean) {
+ val shopdtl = entityManager.find(TShopdtl::class.java, refno, LockModeType.PESSIMISTIC_WRITE)
+ ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
+ "商户流水<$refno>不存在")
+ if (shopdtl.updateBala) {
+ return
+ }
+ recalcShopBalance(shopdtl, shopdtl.amount, overdraft)
+ shopdtl.updateBala = true
+ entityManager.persist(shopdtl)
+ }
+
+ override fun findUnupdatedShopDtl(maxCount: Int): List<TShopdtl> {
+ return entityManager.createQuery("""
+ SELECT p FROM TShopdtl p
+ WHERE p.status='$DTL_STATUS_SUCCESS' and p.updateBala=false
+ ORDER BY p.refno""", TShopdtl::class.java).setMaxResults(maxCount).resultList
+ }
}
\ 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 05b57b2..3c8b3a6 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
@@ -17,8 +17,11 @@
import com.supwisdom.dlpay.framework.util.TradeErrorCode
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
+import org.springframework.transaction.annotation.Propagation
+import org.springframework.transaction.annotation.Transactional
import java.sql.SQLException
import java.sql.Timestamp
+import kotlin.math.absoluteValue
@Service
@@ -44,9 +47,6 @@
@Autowired
private lateinit var sourceTypeService: SourceTypeService
- @Autowired
- private lateinit var shopAccBalanceAsyncTask: ShopAccBalanceAsyncTask
-
private fun preCheck(builder: TransactionBuilder) {
builder.preCheck()
@@ -100,8 +100,7 @@
remark = builder.person().remark
this.status = status
}.also {
- // save persondtl
- persondtlDao.save(it)
+ // persondtlDao.save(it)
transaction.personDtl = it
transaction.person = true
}
@@ -130,6 +129,7 @@
this.oppositeAccName = builder.shop().opposite.getAccountName()
this.remark = builder.shop().remark
this.reverseFlag = TradeDict.REVERSE_FLAG_NONE
+ this.updateBala = false
this.status = status
}.also {
// save shopdtl
@@ -315,14 +315,6 @@
}
override fun success(refno: String, remark: String): TTransactionMain {
- val transaction = successOnAccount(refno, remark)
- if (transaction.status == TradeDict.DTL_STATUS_SUCCESS) {
- shopAccBalanceAsyncTask.updateShopBalance(transaction.refno)
- }
- return transaction
- }
-
- override fun successOnAccount(refno: String, remark: String): TTransactionMain {
val transaction = transactionMainDao.findByRefnoForUpdate(refno)
?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水<$refno>参考号错误")
@@ -377,7 +369,7 @@
val amount = transaction.sumAmountByAccno(
transaction.personDtl.accountNo, Subject.SUBJNO_PERSONAL_DEPOSIT,
PERSON_BALANCE_FLAG, "both")
- if (amount.compareTo(0.0) != 0) {
+ if (amount.absoluteValue.compareTo(0.0) != 0) {
transaction.personDtl?.let {
accountService.recalcAccountBalance(it, amount, overdraft)
transaction.personDtl.accdate = transaction.accdate
@@ -389,16 +381,13 @@
}
if (transaction.shop) {
// update shop balance
- val amount = transaction.sumAmountByAccno(
- transaction.shopDtl.shopaccno, Subject.SUBJNO_MACHANT_INCOME,
- SHOP_BALANCE_FLAG, "both")
- if (amount.compareTo(0.0) != 0) {
-// transaction.shopDtl?.let {
-// shopaccService.recalcShopBalance(it, amount, overdraft)
-// } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
-// "商户流水<${transaction.refno}>不存在")
-// shopAccBalanceAsyncTask.updateShopBalance(transaction.shopDtl.refno)
- }
+// val amount = transaction.sumAmountByAccno(
+// transaction.shopDtl.shopaccno, Subject.SUBJNO_MACHANT_INCOME,
+// SHOP_BALANCE_FLAG, "both")
+// if (amount.absoluteValue.compareTo(0.0) != 0) {
+//
+// }
+ transaction.shopDtl.updateBala = false
transaction.shopDtl.status = TradeDict.DTL_STATUS_SUCCESS
transaction.shopDtl.accdate = transaction.accdate
transaction.shopDtl.remark = remark
@@ -428,4 +417,4 @@
transactionMainDao.save(transaction)
return transaction
}
-}
\ No newline at end of file
+}
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 c2b942a..223a12b 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
@@ -1,7 +1,10 @@
package com.supwisdom.dlpay.api.service
+import com.supwisdom.dlpay.ShopAccBalanceAsyncTask
import com.supwisdom.dlpay.api.TransactionBuilder
import com.supwisdom.dlpay.api.domain.TTransactionMain
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional
@@ -22,9 +25,9 @@
fun fail(refno: String, remark: String): TTransactionMain
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
- fun successOnAccount(refno: String, remark: String): TTransactionMain
-
fun success(refno: String, remark: String): TTransactionMain
+
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
fun success(refno: String): TTransactionMain
// 撤销接口冲正类接口
@@ -58,3 +61,45 @@
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
fun repair(refno: String, remark: String): TTransactionMain
}
+
+@Component
+class TransactionServiceProxy {
+ @Autowired
+ private lateinit var transactionService: TransactionService
+
+ @Autowired
+ private lateinit var shopAccBalanceAsyncTask: ShopAccBalanceAsyncTask
+
+
+ fun init(builder: TransactionBuilder): TTransactionMain {
+ return transactionService.init(builder)
+ }
+
+ fun wip(refno: String): TTransactionMain {
+ return transactionService.wip(refno)
+ }
+
+ fun wip(builder: TransactionBuilder): TTransactionMain {
+ return transactionService.wip(builder)
+ }
+
+ fun fail(refno: String): TTransactionMain {
+ return transactionService.fail(refno)
+ }
+
+ fun fail(refno: String, remark: String): TTransactionMain {
+ return transactionService.fail(refno, remark)
+ }
+
+ fun success(refno: String, remark: String): TTransactionMain {
+ return transactionService.success(refno, remark).also {
+ if (it.shop) {
+ shopAccBalanceAsyncTask.updateShopBalance(it.refno)
+ }
+ }
+ }
+
+ fun success(refno: String): TTransactionMain {
+ return success(refno, "")
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt b/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
index 9dc29ac..74f77fd 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
@@ -3,6 +3,7 @@
import com.supwisdom.dlpay.api.domain.TAccount
import com.supwisdom.dlpay.api.domain.TTransactionMain
import com.supwisdom.dlpay.api.service.TransactionService
+import com.supwisdom.dlpay.api.service.TransactionServiceProxy
import com.supwisdom.dlpay.exception.TransactionCheckException
import com.supwisdom.dlpay.framework.domain.TShopacc
import com.supwisdom.dlpay.framework.domain.TSubject
@@ -337,19 +338,19 @@
}
}
- fun init(transactionService: TransactionService): TTransactionMain {
+ fun init(transactionService: TransactionServiceProxy): TTransactionMain {
return transactionService.init(this)
}
- fun wip(transactionService: TransactionService): TTransactionMain {
+ fun wip(transactionService: TransactionServiceProxy): TTransactionMain {
return transactionService.wip(this)
}
- fun cancel(transactionService: TransactionService, originRefno: String): TTransactionMain {
+ fun cancel(transactionService: TransactionServiceProxy, originRefno: String): TTransactionMain {
TODO("not implement")
}
- fun reverse(transactionService: TransactionService, originRefno: String, amount: Double): TTransactionMain {
+ fun reverse(transactionService: TransactionServiceProxy, originRefno: String, amount: Double): TTransactionMain {
TODO("not implement")
}
}