refactor: 重构记账业务,优化并发逻辑
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 ee43852..91c7bac 100644
--- a/src/main/java/com/supwisdom/dlpay/api/dao/AccountDao.java
+++ b/src/main/java/com/supwisdom/dlpay/api/dao/AccountDao.java
@@ -1,7 +1,6 @@
 package com.supwisdom.dlpay.api.dao;
 
 import com.supwisdom.dlpay.api.domain.TAccount;
-import com.supwisdom.dlpay.api.repositories.TAccountRepository;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TAccount.java b/src/main/java/com/supwisdom/dlpay/api/domain/TAccount.java
index dc97643..b7dac86 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TAccount.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TAccount.java
@@ -2,16 +2,19 @@
 
 import com.supwisdom.dlpay.framework.util.MD5;
 import com.supwisdom.dlpay.framework.util.MoneyUtil;
+import com.supwisdom.dlpay.system.common.DictPool;
 import org.hibernate.annotations.GenericGenerator;
+import org.springframework.beans.factory.annotation.Autowired;
 
 import javax.persistence.*;
+import java.io.Serializable;
 
 @Entity
 @Table(name = "TB_ACCOUNT",
     indexes = {@Index(name = "acc_userid_idx", columnList = "userid"),
         @Index(name = "acc_status_idx", columnList = "status"),
         @Index(name = "acc_subjno_uk", unique = true, columnList = "subjno,userid")})
-public class TAccount {
+public class TAccount implements Serializable {
   @Id
   @GenericGenerator(name = "idGenerator", strategy = "uuid")
   @GeneratedValue(generator = "idGenerator")
@@ -69,8 +72,12 @@
   @Column(name = "CLOSEDATE", length = 8)
   private String closedate;
 
+  @Version
+  @Column(name = "optlock", columnDefinition = "integer DEFAULT 0", nullable = false)
+  private Long version;
+
   @OneToOne
-  @JoinColumn(name = "USERID",insertable = false,updatable = false)
+  @JoinColumn(name = "USERID", insertable = false, updatable = false)
   private TPerson person;
 
   public TAccount() {
@@ -289,4 +296,12 @@
   public void setPerson(TPerson person) {
     this.person = person;
   }
+
+  public Long getVersion() {
+    return version;
+  }
+
+  public void setVersion(Long version) {
+    this.version = version;
+  }
 }
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TAccountDayBal.java b/src/main/java/com/supwisdom/dlpay/api/domain/TAccountDayBal.java
new file mode 100644
index 0000000..f31adb3
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TAccountDayBal.java
@@ -0,0 +1,101 @@
+package com.supwisdom.dlpay.api.domain;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.sql.Timestamp;
+
+@Entity
+@Table(name = "tb_accountdaybal")
+@IdClass(TAccountDayBalPk.class)
+public class TAccountDayBal implements Serializable {
+  @Id
+  @Column(name = "accno", length = 32, nullable = false)
+  private String accno; //账号
+
+  @Id
+  @Column(name = "accdate", length = 8, nullable = false)
+  private String accdate; //记账日期
+
+  @Column(name = "amount", precision = 15, scale = 2)
+  private Double amount;
+
+  @Column(name = "update_time", nullable = false)
+  private Timestamp updateTime;
+
+  @Column(name = "lastRefno", nullable = false, length = 32)
+  private String lastRefno;
+
+  @Column(name = "remark", length = 250)
+  private String remark;
+
+  @Column(name = "checked")
+  private Boolean checked;
+
+  @Version
+  @Column(name = "optlock", columnDefinition = "integer DEFAULT 0", nullable = false)
+  private Long version;
+
+  public String getAccno() {
+    return accno;
+  }
+
+  public void setAccno(String accno) {
+    this.accno = accno;
+  }
+
+  public String getAccdate() {
+    return accdate;
+  }
+
+  public void setAccdate(String accdate) {
+    this.accdate = accdate;
+  }
+
+  public Double getAmount() {
+    return amount;
+  }
+
+  public void setAmount(Double amount) {
+    this.amount = amount;
+  }
+
+  public Timestamp getUpdateTime() {
+    return updateTime;
+  }
+
+  public void setUpdateTime(Timestamp updateTime) {
+    this.updateTime = updateTime;
+  }
+
+  public String getLastRefno() {
+    return lastRefno;
+  }
+
+  public void setLastRefno(String lastRefno) {
+    this.lastRefno = lastRefno;
+  }
+
+  public String getRemark() {
+    return remark;
+  }
+
+  public void setRemark(String remark) {
+    this.remark = remark;
+  }
+
+  public Boolean getChecked() {
+    return checked;
+  }
+
+  public void setChecked(Boolean checked) {
+    this.checked = checked;
+  }
+
+  public Long getVersion() {
+    return version;
+  }
+
+  public void setVersion(Long version) {
+    this.version = version;
+  }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TAccountDayBalPk.java b/src/main/java/com/supwisdom/dlpay/api/domain/TAccountDayBalPk.java
new file mode 100644
index 0000000..d811471
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TAccountDayBalPk.java
@@ -0,0 +1,46 @@
+package com.supwisdom.dlpay.api.domain;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import java.io.Serializable;
+import java.util.Objects;
+
+public class TAccountDayBalPk implements Serializable {
+  @Id
+  @Column(name = "accno", length = 32, nullable = false)
+  private String accno; //账号
+
+  @Id
+  @Column(name = "accdate", length = 8, nullable = false)
+  private String accdate; //记账日期
+
+  public String getAccno() {
+    return accno;
+  }
+
+  public void setAccno(String accno) {
+    this.accno = accno;
+  }
+
+  public String getAccdate() {
+    return accdate;
+  }
+
+  public void setAccdate(String accdate) {
+    this.accdate = accdate;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    TAccountDayBalPk that = (TAccountDayBalPk) o;
+    return Objects.equals(accno, that.accno) &&
+        Objects.equals(accdate, that.accdate);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(accno, accdate);
+  }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TDebitCreditDtlPK.java b/src/main/java/com/supwisdom/dlpay/api/domain/TDebitCreditDtlPK.java
index b8d7973..5a0a48b 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TDebitCreditDtlPK.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TDebitCreditDtlPK.java
@@ -10,7 +10,7 @@
   private String refno;
 
   @Id
-  @Column(name = "SEQNO", nullable = false, precision = 1)
+  @Column(name = "SEQNO", nullable = false, precision = 2)
   private Integer seqno;
 
   public String getRefno() {
diff --git a/src/main/java/com/supwisdom/dlpay/api/repositories/AccountService.java b/src/main/java/com/supwisdom/dlpay/api/repositories/AccountService.java
new file mode 100644
index 0000000..5e976e8
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/api/repositories/AccountService.java
@@ -0,0 +1,11 @@
+package com.supwisdom.dlpay.api.repositories;
+
+import com.supwisdom.dlpay.api.domain.TPersondtl;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Transactional;
+
+public interface AccountService {
+
+  @Transactional(isolation = Isolation.SERIALIZABLE)
+  void recalcAccountBalance(TPersondtl dtl, Double amount, boolean overdraft);
+}
diff --git a/src/main/java/com/supwisdom/dlpay/api/repositories/ShopaccService.java b/src/main/java/com/supwisdom/dlpay/api/repositories/ShopaccService.java
new file mode 100644
index 0000000..cea6e08
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/api/repositories/ShopaccService.java
@@ -0,0 +1,10 @@
+package com.supwisdom.dlpay.api.repositories;
+
+import com.supwisdom.dlpay.api.domain.TShopdtl;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Transactional;
+
+public interface ShopaccService {
+  @Transactional(isolation = Isolation.READ_COMMITTED)
+  void recalcShopBalance(TShopdtl dtl, Double amount, boolean overdraft);
+}
diff --git a/src/main/java/com/supwisdom/dlpay/api/repositories/TAccountRepository.java b/src/main/java/com/supwisdom/dlpay/api/repositories/TAccountRepository.java
deleted file mode 100644
index 222391f..0000000
--- a/src/main/java/com/supwisdom/dlpay/api/repositories/TAccountRepository.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.supwisdom.dlpay.api.repositories;
-
-import com.supwisdom.dlpay.api.domain.TAccount;
-import com.supwisdom.dlpay.api.domain.TPersondtl;
-
-public interface TAccountRepository {
-  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
deleted file mode 100644
index 291bd1c..0000000
--- a/src/main/java/com/supwisdom/dlpay/api/repositories/TShopaccRepository.java
+++ /dev/null
@@ -1,7 +0,0 @@
-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/framework/data/SystemDateTime.java b/src/main/java/com/supwisdom/dlpay/framework/data/SystemDateTime.java
index baaa274..0ba8274 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/data/SystemDateTime.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/data/SystemDateTime.java
@@ -1,5 +1,6 @@
 package com.supwisdom.dlpay.framework.data;
 
+import java.sql.Timestamp;
 import java.util.Date;
 
 public interface SystemDateTime {
@@ -10,4 +11,6 @@
   String getHostdatetime();
 
   Date getSysdate();
+
+  Timestamp getCurrentTimestamp();
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/service/impl/SystemUtilServiceImpl.java b/src/main/java/com/supwisdom/dlpay/framework/service/impl/SystemUtilServiceImpl.java
index eee9e5a..ff86a29 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/service/impl/SystemUtilServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/service/impl/SystemUtilServiceImpl.java
@@ -13,6 +13,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.sql.Timestamp;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
@@ -61,6 +62,11 @@
     public Date getSysdate() {
       return this.now;
     }
+
+    @Override
+    public Timestamp getCurrentTimestamp() {
+      return new Timestamp(this.now.getTime());
+    }
   }
 
   /**
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 336239e..71df139 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
@@ -12,7 +12,7 @@
 
   /**
    * 账户不存在
-   * */
+   */
   public static final int ACCOUNT_NOT_EXISTS = 10001;
 
   /**
@@ -41,78 +41,78 @@
   public static final int TRANSACTION_HAS_CANCELED = 10006;
   /**
    * 商户不存在
-   * */
+   */
   public static final int SHOP_NOT_EXISTS = 10007;
 
   /**
    * 科目不存在
-   * */
+   */
   public static final int SUBJECT_NOT_EXISTS = 10008;
 
   /**
    * 外部流水号重复
-   * */
+   */
   public static final int OUTTRADENO_ALREADY_EXISTS = 10009;
 
   /**
    * 账户TAC校验异常
-   * */
+   */
   public static final int ACCOUNT_TAC_ERROR = 10010;
 
   /**
    * 账户余额超上限
-   * */
+   */
   public static final int OVERFLOW_BALANCE_ERROR = 10011;
 
   /**
    * 未指定明确的交易结束状态
-   * */
+   */
   public static final int TRANSDTL_STATUS_ERROR = 10012;
 
   /**
    * 非初始化流水
-   * */
+   */
   public static final int TRANSDTL_STATUS_NOT_INIT = 10013;
 
   /**
    * 账户交易繁忙
-   * */
+   */
   public static final int ACCOUNT_TRADE_BUSY = 10014;
 
   /**
    * 非等待锁查询超时异常
-   * */
+   */
   public static final int LOCK_READ_TIMEOUT = 10015;
 
   /**
-   *  卡已挂失
-   * */
+   * 卡已挂失
+   */
   public static final int ACCOUNT_IS_LOSS = 10016;
 
   /**
-   *  卡已锁定
-   * */
+   * 卡已锁定
+   */
   public static final int ACCOUNT_IS_LOCKED = 10017;
 
   /**
    * 费用类别未定义
-   * */
+   */
   public static final int FEETYPE_NOT_EXISTS = 10018;
 
   /**
    * 费用类别不支持
-   * */
+   */
   public static final int FEETYPE_NOT_NOSUPPORT = 10019;
 
 
   /**
    * 请求参数错误
-   * */
+   */
   public static final int REQUEST_PARAM_ERROR = 20000;
 
   /**
    * 请求参数错误签名错误
-   * */
+   */
   public static final int REQUEST_SIGN_ERROR = 20001;
 
   /**
@@ -131,4 +131,6 @@
 
   public static final int BUSINESS_PAYTYPE_NOSUPPORT = 30003; //支付方式不支持
 
+  public static final int UNHANLDED_EXCEPTION = 300004; // 未处理异常
+
 }
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt b/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt
index f47651d..e3e2cb5 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt
@@ -23,7 +23,7 @@
     fun handleException(ex: Exception, request: HttpServletRequest): ResponseEntity<Any> {
         logger.error { "Request unhandler exception, url<${request.requestURI}>, ex<${ex.cause}>" }
         return ResponseEntity.ok().body(ResponseBodyBuilder.create()
-                .exception(TradeErrorCode.BUSINESS_DEAL_ERROR, ex.cause))
+                .exception(TradeErrorCode.UNHANLDED_EXCEPTION, ex.cause))
     }
 }
 
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
deleted file mode 100644
index e14f947..0000000
--- a/src/main/kotlin/com/supwisdom/dlpay/api/repositories/repository_impl.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-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,
-                    "账户余额已被更新")
-        }
-
-        return entityManager.createQuery("update TAccount a set a.availbal=a.availbal+?1, a.balance=a.balance+?1 " +
-                "where a.accno=?2 and a.availbal=?3")?.run {
-            setParameter(1, amount)
-            setParameter(2, accno)
-            setParameter(3, avaibal)
-            executeUpdate()
-        } ?: throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "更新个人账户余额错误")
-    }
-
-    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).also { count ->
-                if (count == 1) {
-                    dtl.befbal = it.availbal
-                }
-            }
-        } ?: 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}>商户账户不存在")
-
-        return entityManager.createQuery("update TShopacc c set c.balance=c.balance+?1" +
-                " where c.shopaccno=?2 and c.balance=?3")?.run {
-            setParameter(1, amount)
-            setParameter(2, dtl.shopaccno)
-            setParameter(3, shopacc.balance)
-            executeUpdate()
-        } ?: throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR,
-                "交易流水<${dtl.refno}>未找到指定商户账户")
-    }
-}
\ 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
new file mode 100644
index 0000000..9622f61
--- /dev/null
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt
@@ -0,0 +1,93 @@
+package com.supwisdom.dlpay.api.service.impl
+
+import com.supwisdom.dlpay.api.domain.*
+import com.supwisdom.dlpay.api.repositories.AccountService
+import com.supwisdom.dlpay.api.repositories.ShopaccService
+import com.supwisdom.dlpay.exception.TransactionProcessException
+import com.supwisdom.dlpay.framework.domain.TShopacc
+import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.TradeErrorCode
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Repository
+import javax.persistence.EntityManager
+import javax.persistence.LockModeType
+import javax.persistence.OptimisticLockException
+import javax.persistence.PersistenceContext
+
+@Repository
+class AccountServiceImpl : AccountService {
+
+    @PersistenceContext
+    private lateinit var entityManager: EntityManager
+
+    @Autowired
+    lateinit var systemUtilServcie: SystemUtilService
+
+    private fun newAccounDayBal(dtl: TPersondtl, account: TAccount) = TAccountDayBal().apply {
+        accno = account.accno
+        accdate = dtl.accdate
+        amount = 0.0
+        checked = false
+    }
+
+    private fun doRecalcAccountBalance(dtl: TPersondtl, account: TAccount): TAccountDayBal {
+        val accountDayBal = entityManager.find(TAccountDayBal::class.java,
+                TAccountDayBalPk().also {
+                    it.accno = account.accno
+                    it.accdate = dtl.accdate
+                }, LockModeType.OPTIMISTIC) ?: newAccounDayBal(dtl, account)
+
+        accountDayBal.also {
+            it.lastRefno = dtl.refno
+            it.amount += dtl.amount
+            it.updateTime = systemUtilServcie.sysdatetime.currentTimestamp
+        }.also {
+            entityManager.persist(it)
+        }
+
+        return accountDayBal
+    }
+
+    override fun recalcAccountBalance(dtl: TPersondtl, amount: Double, overdraft: Boolean) {
+        entityManager.find(TAccount::class.java, dtl.accountNo, LockModeType.OPTIMISTIC)
+                ?.let { account ->
+                    if (!overdraft && account.availbal + dtl.amount < 0) {
+                        throw TransactionProcessException(TradeErrorCode.SHORT_BALANCE_ERROR, "个人账户余额不足")
+                    }
+                    dtl.befbal = account.availbal
+                    doRecalcAccountBalance(dtl, account)
+                    account.availbal += dtl.amount
+                    account.balance += dtl.amount
+                    account.lasttransdate = dtl.accdate
+                    try {
+                        entityManager.persist(account)
+                    } catch (ex: OptimisticLockException) {
+                        throw TransactionProcessException(TradeErrorCode.ACCOUNT_TRADE_BUSY,
+                                "个人账户被被更新")
+                    }
+
+                } ?: throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR,
+                "交易流水<${dtl.refno}>未找到指定个人账户")
+    }
+}
+
+@Repository
+class ShopaccServiceImpl : ShopaccService {
+
+    @PersistenceContext
+    private lateinit var entityManager: EntityManager
+
+    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}>商户账户不存在")
+
+        shopacc.balance += amount
+        if (shopacc.balance < 0.0 && !overdraft) {
+            throw TransactionProcessException(TradeErrorCode.SHORT_BALANCE_ERROR,
+                    "商户账户余额不足")
+        }
+
+        entityManager.persist(shopacc)
+    }
+}
\ 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 d7e8895..ab253c0 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
@@ -1,10 +1,11 @@
 package com.supwisdom.dlpay.api.service.impl
 
 import com.supwisdom.dlpay.api.TransactionBuilder
-import com.supwisdom.dlpay.api.dao.*
+import com.supwisdom.dlpay.api.dao.PersondtlDao
+import com.supwisdom.dlpay.api.dao.TransactionMainDao
 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.repositories.AccountService
+import com.supwisdom.dlpay.api.repositories.ShopaccService
 import com.supwisdom.dlpay.api.service.SourceTypeService
 import com.supwisdom.dlpay.api.service.TransactionService
 import com.supwisdom.dlpay.exception.TransactionCheckException
@@ -28,22 +29,22 @@
     }
 
     @Autowired
-    lateinit var transactionMainDao: TransactionMainDao
+    private lateinit var transactionMainDao: TransactionMainDao
 
     @Autowired
-    lateinit var persondtlDao: PersondtlDao
+    private lateinit var persondtlDao: PersondtlDao
 
     @Autowired
-    lateinit var accountRepository: TAccountRepositoryImpl
+    private lateinit var accountService: AccountService
 
     @Autowired
-    lateinit var shopaccRepository: ShopaccRepositoryImpl
+    private lateinit var shopaccService: ShopaccService
 
     @Autowired
-    lateinit var systemUtilService: SystemUtilService
+    private lateinit var systemUtilService: SystemUtilService
 
     @Autowired
-    lateinit var sourceTypeService: SourceTypeService
+    private lateinit var sourceTypeService: SourceTypeService
 
     private fun preCheck(builder: TransactionBuilder) {
         builder.preCheck()
@@ -369,10 +370,7 @@
                     PERSON_BALANCE_FLAG, "both")
             if (amount.compareTo(0.0) != 0) {
                 transaction.personDtl?.let {
-                    if (accountRepository.recalcAccountBalance(it, amount, overdraft) != 1) {
-                        throw TransactionProcessException(TradeErrorCode.ACCOUNT_TRADE_BUSY,
-                                "个人账户交易冲突")
-                    }
+                    accountService.recalcAccountBalance(it, amount, overdraft)
                     transaction.personDtl.accdate = transaction.accdate
                 } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
                         "个人流水<${transaction.refno}>不存在")
@@ -387,10 +385,7 @@
                     SHOP_BALANCE_FLAG, "both")
             if (amount.compareTo(0.0) != 0) {
                 transaction.shopDtl?.let {
-                    if (shopaccRepository.recalcShopBalance(it, it.amount, overdraft) != 1) {
-                        throw TransactionProcessException(TradeErrorCode.ACCOUNT_TRADE_BUSY,
-                                "商户账户交易冲突")
-                    }
+                    shopaccService.recalcShopBalance(it, it.amount, overdraft)
                 } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
                         "商户流水<${transaction.refno}>不存在")
             }