锁修改
diff --git a/src/main/java/com/supwisdom/dlpay/consume/dao/AccountDao.java b/src/main/java/com/supwisdom/dlpay/consume/dao/AccountDao.java
index 5cae32d..f102258 100644
--- a/src/main/java/com/supwisdom/dlpay/consume/dao/AccountDao.java
+++ b/src/main/java/com/supwisdom/dlpay/consume/dao/AccountDao.java
@@ -12,7 +12,6 @@
 public interface AccountDao extends JpaRepository<TAccount, String> {
 
   @Lock(LockModeType.PESSIMISTIC_WRITE)
-  @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="5000")})
   @Query("select a from TAccount a where a.accno = ?1")
   TAccount getByAccnoForUpdate(String accno);
 
@@ -21,6 +20,14 @@
   @Query("select a from TAccount a where a.accno = ?1")
   TAccount getByAccnoForUpdateNowait(String accno);
 
-
   TAccount findByUserid(String userid);
+
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
+  @Query("select a from TAccount a where a.userid = ?1")
+  TAccount getByUseridForUpdate(String userid);
+
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
+  @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "0")})
+  @Query("select a from TAccount a where a.userid = ?1")
+  TAccount getByUseridForUpdateNowait(String userid);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/consume/dao/UserdtlDao.java b/src/main/java/com/supwisdom/dlpay/consume/dao/UserdtlDao.java
index e465fbd..67cbeff 100644
--- a/src/main/java/com/supwisdom/dlpay/consume/dao/UserdtlDao.java
+++ b/src/main/java/com/supwisdom/dlpay/consume/dao/UserdtlDao.java
@@ -15,7 +15,11 @@
   TUserdtl findByRefno(String refno);
 
   @Lock(LockModeType.PESSIMISTIC_WRITE)
-  @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="0")})
   @Query("select dtl from TUserdtl  dtl where dtl.refno = ?1")
   TUserdtl findByRefnoForUpdate(String refno);
+
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
+  @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="0")})
+  @Query("select dtl from TUserdtl  dtl where dtl.refno = ?1")
+  TUserdtl findByRefnoForUpdateNowait(String refno);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/dao/PeriodDao.java b/src/main/java/com/supwisdom/dlpay/framework/dao/PeriodDao.java
index 8ec82ca..aa05bd7 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/dao/PeriodDao.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/dao/PeriodDao.java
@@ -15,7 +15,7 @@
   @Query(value = "from TPeriod t where t.periodYear=:periodyear and t.periodMonth=:periodmonth ")
   TPeriod getPeriod(@Param("periodyear") Integer periodyear, @Param("periodmonth") Integer periodmonth);
 
-  @Lock(LockModeType.PESSIMISTIC_FORCE_INCREMENT)
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
   @Query(value = "from TPeriod t where t.periodYear=:periodyear and t.periodMonth=:periodmonth ")
   TPeriod getTPeriodWithLock(@Param("periodyear") Integer periodyear, @Param("periodmonth") Integer periodmonth);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/dao/ShopaccDao.java b/src/main/java/com/supwisdom/dlpay/framework/dao/ShopaccDao.java
index 1b351b2..27e7185 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/dao/ShopaccDao.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/dao/ShopaccDao.java
@@ -3,10 +3,12 @@
 import com.supwisdom.dlpay.framework.data.ExistBean;
 import com.supwisdom.dlpay.framework.domain.TShopacc;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Lock;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.jpa.repository.QueryHints;
 import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
+import javax.persistence.LockModeType;
 
 import javax.persistence.QueryHint;
 import java.util.List;
@@ -28,7 +30,12 @@
 
   TShopacc findByShopid(Integer shopid);
 
-  @Query(value = "select s from TShopacc  s where s.shopid = ?1")
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
   @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="0")})
-  TShopacc getShopAccForUpdate(Integer shopid);
+  @Query("select a from TShopacc a where a.shopid=?1")
+  TShopacc getShopaccWithLockNowait(Integer shopid);
+
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
+  @Query("select a from TShopacc a where a.shopid=?1")
+  TShopacc getShopaccWithLock(Integer shopid);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/dao/ShopaccbalDao.java b/src/main/java/com/supwisdom/dlpay/framework/dao/ShopaccbalDao.java
index 1721e6e..1a769bb 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/dao/ShopaccbalDao.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/dao/ShopaccbalDao.java
@@ -16,7 +16,7 @@
   @Query(value = "select t.* from TB_SHOPACCBAL t left join (select shopaccno from TB_SHOPACCDAY where accdate=:lastsettday ) a on t.shopaccno=a.shopaccno where a.shopaccno is null ", nativeQuery = true)
   List<TShopaccbal> getUnsettleShopacc(@Param("lastsettday") String lastsettday);
 
-  @Lock(LockModeType.PESSIMISTIC_FORCE_INCREMENT)
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
   @Query(value = "from TShopaccbal where shopaccno=:shopaccno ")
   TShopaccbal getTShopaccbalByIdWithLock(@Param("shopaccno")String shopaccno);
 
diff --git a/src/main/java/com/supwisdom/dlpay/framework/dao/SubjectDao.java b/src/main/java/com/supwisdom/dlpay/framework/dao/SubjectDao.java
index a694eaa..328a01a 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/dao/SubjectDao.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/dao/SubjectDao.java
@@ -23,4 +23,6 @@
 
   @Query(value = "select subjname from TSubject where subjno=:subjno ")
   String getSubjectname(@Param("subjno") String subjno);
+
+  TSubject findBySubjno(String subjno);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/dao/SubjectbalDao.java b/src/main/java/com/supwisdom/dlpay/framework/dao/SubjectbalDao.java
index b2638c1..73b01cf 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/dao/SubjectbalDao.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/dao/SubjectbalDao.java
@@ -27,7 +27,7 @@
   @Query(value = "select case when :balflag=1 then sum(drbal) else sum(crbal) end as amount from tb_subjectbal where subjno in (select subjno from tb_subject where endflag=1 and balflag=:balflag )",nativeQuery = true)
   Double getSumEndsubjectBalByEndflag(@Param("balflag")Integer balflag);
 
-  @Lock(LockModeType.PESSIMISTIC_FORCE_INCREMENT)
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
   @Query("from TSubjectbal where subjno=:subjno ")
   TSubjectbal getTSubjectbalBySubjnoWithLock(@Param("subjno")String subjno);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/dao/TaskLockDao.java b/src/main/java/com/supwisdom/dlpay/framework/dao/TaskLockDao.java
index 9199a6a..6c36c5d 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/dao/TaskLockDao.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/dao/TaskLockDao.java
@@ -13,7 +13,7 @@
 @Repository
 public interface TaskLockDao extends JpaRepository<TTaskLock, String> {
 
-  @Lock(LockModeType.PESSIMISTIC_FORCE_INCREMENT)
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
   @Query("select a from TTaskLock a where a.taskcode=:taskcode")
   TTaskLock getTaskLockWithLock(@Param("taskcode") String taskcode);
 
diff --git a/src/main/java/com/supwisdom/dlpay/framework/dao/TranstypeDao.java b/src/main/java/com/supwisdom/dlpay/framework/dao/TranstypeDao.java
index 89d1da4..a276c61 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/dao/TranstypeDao.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/dao/TranstypeDao.java
@@ -2,7 +2,9 @@
 
 import com.supwisdom.dlpay.framework.domain.TTranstype;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
 
+@Repository
 public interface TranstypeDao extends JpaRepository<TTranstype, Integer> {
-
+  TTranstype findByTranstype(Integer transtype);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/dao/VoucherDao.java b/src/main/java/com/supwisdom/dlpay/framework/dao/VoucherDao.java
index 18a4769..cb618f9 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/dao/VoucherDao.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/dao/VoucherDao.java
@@ -19,7 +19,7 @@
   @Query(value="delete from TB_VOUCHER where POSTFLAG=0 ",nativeQuery = true)
   void deleteUnpostVoucher();
 
-  @Lock(LockModeType.PESSIMISTIC_FORCE_INCREMENT)
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
   @Query(value = "from TVoucher where postflag=0 order by voucherid ")
   List<TVoucher> getSettleVouchers();
 
@@ -32,7 +32,7 @@
   @Query(value = "select sum(va.dramt) as dramt, sum(va.cramt) as cramt  from TB_VOUCHERENTRY va,TB_VOUCHER vb where va.voucherid=vb.voucherid and vb.voucherdate=:voucherdate and va.subjno=:subjno ", nativeQuery = true)
   MerchBean getSettleSuminfo(@Param("voucherdate") Integer voucherdate, @Param("subjno") String subjno);
 
-  @Lock(LockModeType.PESSIMISTIC_FORCE_INCREMENT)
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
   @Query(value = "from TVoucher where voucherid=:voucherid ")
   TVoucher findByVoucheridWithLock(@Param("voucherid") String voucherid);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/dao/VoucherEntryDao.java b/src/main/java/com/supwisdom/dlpay/framework/dao/VoucherEntryDao.java
index 893bd2a..ba4ba73 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/dao/VoucherEntryDao.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/dao/VoucherEntryDao.java
@@ -18,7 +18,7 @@
   @Query(value = "from TVoucherEntry where voucherid in (select voucherid from TVoucher where voucherdate=:voucherdate) order by subjno,accno,voucherid ")
   List<TVoucherEntry> getVoucherEntryByVoucherdate(@Param("voucherdate") Integer voucherdate);
 
-  @Lock(LockModeType.PESSIMISTIC_FORCE_INCREMENT)
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
   @Query(value = "from TVoucherEntry t where t.voucherid=:voucherid ")
   List<TVoucherEntry> getVoucherEntryByVoucherid(@Param("voucherid")String voucherid);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/dao/VouchernoCtlDao.java b/src/main/java/com/supwisdom/dlpay/framework/dao/VouchernoCtlDao.java
index 62d3827..46b4b23 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/dao/VouchernoCtlDao.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/dao/VouchernoCtlDao.java
@@ -14,7 +14,7 @@
   @Query(value = "update TB_VOUCHERNOCTL set PERIOD_MONTH=:peridmonth,VOUCHERNO=:voucherno where VOUCHERTYPE=1 ", nativeQuery = true)
   void updateVoucherno(@Param("peridmonth") int peridmonth, @Param("voucherno") int voucherno);
 
-  @Lock(LockModeType.PESSIMISTIC_FORCE_INCREMENT)
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
   @Query(value = "from TVouchernoCtl where vouchertype=1 ")
   TVouchernoCtl getVoucherno();
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/domain/TTranstype.java b/src/main/java/com/supwisdom/dlpay/framework/domain/TTranstype.java
index b098ce3..6f0c036 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/domain/TTranstype.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/domain/TTranstype.java
@@ -10,46 +10,46 @@
 public class TTranstype {
   @Id
   @Column(name = "TRANSTYPE", nullable = false, precision = 4)
-  private Integer TRANSTYPE;
+  private Integer transtype;
 
   @Column(name = "DRSUBJNO", length = 10)
-  private String DRSUBJNO;
+  private String drsubjno;
 
   @Column(name = "CRSUBJNO", length = 10)
-  private String CRSUBJNO;
+  private String crsubjno;
 
   @Column(name = "SUMMARY", length = 200)
-  private String SUMMARY;
+  private String summary;
 
-  public Integer getTRANSTYPE() {
-    return TRANSTYPE;
+  public Integer getTranstype() {
+    return transtype;
   }
 
-  public void setTRANSTYPE(Integer TRANSTYPE) {
-    this.TRANSTYPE = TRANSTYPE;
+  public void setTranstype(Integer transtype) {
+    this.transtype = transtype;
   }
 
-  public String getDRSUBJNO() {
-    return DRSUBJNO;
+  public String getDrsubjno() {
+    return drsubjno;
   }
 
-  public void setDRSUBJNO(String DRSUBJNO) {
-    this.DRSUBJNO = DRSUBJNO;
+  public void setDrsubjno(String drsubjno) {
+    this.drsubjno = drsubjno;
   }
 
-  public String getCRSUBJNO() {
-    return CRSUBJNO;
+  public String getCrsubjno() {
+    return crsubjno;
   }
 
-  public void setCRSUBJNO(String CRSUBJNO) {
-    this.CRSUBJNO = CRSUBJNO;
+  public void setCrsubjno(String crsubjno) {
+    this.crsubjno = crsubjno;
   }
 
-  public String getSUMMARY() {
-    return SUMMARY;
+  public String getSummary() {
+    return summary;
   }
 
-  public void setSUMMARY(String SUMMARY) {
-    this.SUMMARY = SUMMARY;
+  public void setSummary(String summary) {
+    this.summary = summary;
   }
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/service/impl/DayendSettleServiceImpl.java b/src/main/java/com/supwisdom/dlpay/framework/service/impl/DayendSettleServiceImpl.java
index b57c657..ea02de7 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/service/impl/DayendSettleServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/service/impl/DayendSettleServiceImpl.java
@@ -6,10 +6,7 @@
 import com.supwisdom.dlpay.framework.domain.*;
 import com.supwisdom.dlpay.framework.service.DayendSettleService;
 import com.supwisdom.dlpay.framework.service.SystemUtilService;
-import com.supwisdom.dlpay.framework.util.DateUtil;
-import com.supwisdom.dlpay.framework.util.MoneyUtil;
-import com.supwisdom.dlpay.framework.util.StringUtil;
-import com.supwisdom.dlpay.framework.util.TradeDict;
+import com.supwisdom.dlpay.framework.util.*;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -505,7 +502,7 @@
 
     //明细
     for (TVoucherEntry entry : entryList) {
-      if (TradeDict.SUBJNO_SHOP.equals(entry.getSubjno())) {
+      if (Subject.SUBJNO_MACHANT_INCOME.equals(entry.getSubjno())) {
         TShopaccbal tShopaccbal = shopaccbalDao.getTShopaccbalByIdWithLock(entry.getAccno());
         if (null == tShopaccbal) {
           throw new Exception("商户表商户账号[" + entry.getAccno() + "]不存在");
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/APIRequest.java b/src/main/java/com/supwisdom/dlpay/framework/util/APIRequest.java
new file mode 100644
index 0000000..6679181
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/APIRequest.java
@@ -0,0 +1,41 @@
+package com.supwisdom.dlpay.framework.util;
+
+public class APIRequest {
+  private String app_id;
+  private String sign;
+  private String sign_method;
+  private String timestamp;
+
+  public String getApp_id() {
+    return app_id;
+  }
+
+  public void setApp_id(String app_id) {
+    this.app_id = app_id;
+  }
+
+  public String getSign() {
+    return sign;
+  }
+
+  public void setSign(String sign) {
+    this.sign = sign;
+  }
+
+  public String getSign_method() {
+    return sign_method;
+  }
+
+  public void setSign_method(String sign_method) {
+    this.sign_method = sign_method;
+  }
+
+  public String getTimestamp() {
+    return timestamp;
+  }
+
+  public void setTimestamp(String timestamp) {
+    this.timestamp = timestamp;
+  }
+
+}
diff --git a/src/main/java/com/supwisdom/dlpay/util/HmacUtil.java b/src/main/java/com/supwisdom/dlpay/framework/util/HmacUtil.java
similarity index 97%
rename from src/main/java/com/supwisdom/dlpay/util/HmacUtil.java
rename to src/main/java/com/supwisdom/dlpay/framework/util/HmacUtil.java
index 832c699..0978e28 100644
--- a/src/main/java/com/supwisdom/dlpay/util/HmacUtil.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/HmacUtil.java
@@ -1,6 +1,4 @@
-package com.supwisdom.dlpay.util;
-
-import com.supwisdom.dlpay.framework.util.DateUtil;
+package com.supwisdom.dlpay.framework.util;
 
 import javax.crypto.Mac;
 import javax.crypto.spec.SecretKeySpec;
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 1c4e046..6c97c50 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
@@ -45,7 +45,7 @@
   public static final int SHOP_NOT_EXISTS = 10007;
 
   /**
-   * 商户不存在
+   * 科目不存在
    * */
   public static final int SUBJECT_NOT_EXISTS = 10008;
 
@@ -74,4 +74,14 @@
    * */
   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;
+
 }
diff --git a/src/main/kotlin/com/supwisdom/dlpay/consume/ThirdPayCall.kt b/src/main/kotlin/com/supwisdom/dlpay/consume/ThirdPayCall.kt
index 52efca0..3defd76 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/consume/ThirdPayCall.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/consume/ThirdPayCall.kt
@@ -8,7 +8,7 @@
 import com.supwisdom.dlpay.consume.bean.SupYktResp
 import com.supwisdom.dlpay.consume.domain.TUserdtl
 import com.supwisdom.dlpay.framework.util.MoneyUtil
-import com.supwisdom.dlpay.util.HmacUtil
+import com.supwisdom.dlpay.framework.util.HmacUtil
 
 /**
  * Created by shuwei on 2019/4/11.
diff --git a/src/main/kotlin/com/supwisdom/dlpay/consume/comsume_builder.kt b/src/main/kotlin/com/supwisdom/dlpay/consume/comsume_builder.kt
index 9c49367..2d1eeb6 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/consume/comsume_builder.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/consume/comsume_builder.kt
@@ -51,7 +51,7 @@
     @Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY")
     fun <T> get(): T {
         return when (idType) {
-            IDTYPE_PERSON -> builder.accountUtil.readAccount(accountId)
+            IDTYPE_PERSON -> builder.accountUtil.readAccountForUpdateNowait(accountId)
             IDTYPE_SHOP -> builder.accountUtil.readShopAcc(accountId.toInt())
             IDTYPE_SUBJECT -> builder.accountUtil.readSubject(accountId)
             IDTYPE_TRANSTYPE -> builder.accountUtil.readTranstype(accountId.toInt())
@@ -62,9 +62,9 @@
     @Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY")
     fun <T> withLock(nowait: Boolean): T {
         return when (idType) {
-            IDTYPE_PERSON -> builder.accountUtil.readAccountForUpdate(accountId, true)
-            IDTYPE_SHOP -> builder.accountUtil.readShopAccForUpdate(accountId.toInt(), true)
-            IDTYPE_SUBJECT -> builder.accountUtil.readSubjectForUpdate(accountId, true)
+            IDTYPE_PERSON -> builder.accountUtil.readAccountForUpdateNowait(accountId)
+            IDTYPE_SHOP -> builder.accountUtil.readShopAcc(accountId.toInt())
+            IDTYPE_SUBJECT -> builder.accountUtil.readSubject(accountId)
             IDTYPE_TRANSTYPE -> builder.accountUtil.readTranstype(accountId.toInt())
             else -> throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "账户类型未知type<$idType>")
         } as T
diff --git a/src/main/kotlin/com/supwisdom/dlpay/consume/service/impl/pay_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/consume/service/impl/pay_service_impl.kt
index 176a67d..32883ae 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/consume/service/impl/pay_service_impl.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/consume/service/impl/pay_service_impl.kt
@@ -9,6 +9,7 @@
 import com.supwisdom.dlpay.consume.domain.TUserdtl
 import com.supwisdom.dlpay.consume.service.AccountUtilServcie
 import com.supwisdom.dlpay.consume.service.PersonBalancePayService
+import com.supwisdom.dlpay.exception.TransactionException
 import com.supwisdom.dlpay.exception.TransactionProcessException
 import com.supwisdom.dlpay.framework.dao.ShopaccDao
 import com.supwisdom.dlpay.framework.dao.SubjectDao
@@ -18,7 +19,9 @@
 import com.supwisdom.dlpay.framework.domain.TTranstype
 import com.supwisdom.dlpay.framework.service.SystemUtilService
 import com.supwisdom.dlpay.framework.util.*
+import org.hibernate.exception.LockTimeoutException
 import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.dao.CannotAcquireLockException
 import org.springframework.stereotype.Service
 import javax.persistence.EntityManager
 import javax.persistence.PersistenceContext
@@ -26,6 +29,7 @@
 
 @Service
 class AccountUtilServcieImpl : AccountUtilServcie {
+
     @Autowired
     lateinit var accountDao: AccountDao
 
@@ -39,42 +43,36 @@
     lateinit var transtypeDao: TranstypeDao
 
 
-    override fun readAccountForUpdate(userid: String, nowait: Boolean): TAccount {
-        return accountDao.getByAccnoForUpdateNowait(userid)
+    override fun readAccountForUpdateNowait(userid: String): TAccount {
+        return try {
+            accountDao.getByUseridForUpdateNowait(userid)
+                    ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "账户<$userid>不存在")
+        } catch (ex: Exception) {
+            when (ex) {
+                is CannotAcquireLockException, is LockTimeoutException -> throw TransactionException(TradeErrorCode.ACCOUNT_TRADE_BUSY, "账户<$userid>交易繁忙,请稍后再试")
+                else -> throw ex
+            }
+        }
     }
 
     override fun readAccount(userid: String): TAccount {
-        accountDao.findByUserid(userid).let {
-            if (null != it) {
-                return it
-            }
-            throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "账户<$userid>不存在")
-        }
-    }
-
-    override fun readShopAccForUpdate(shopId: Int, nowait: Boolean): TShopacc {
-        return shopaccDao.getShopAccForUpdate(shopId)
+        return accountDao.findByUserid(userid)
+                ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "账户<$userid>不存在")
     }
 
     override fun readShopAcc(shopId: Int): TShopacc {
-        shopaccDao.findByShopid(shopId).let {
-            if (null != it) {
-                return it
-            }
-            throw TransactionProcessException(TradeErrorCode.SHOP_NOT_EXISTS, "商户<$shopId>不存在")
-        }
-    }
-
-    override fun readSubjectForUpdate(subjno: String, nowait: Boolean): TSubject {
-        return subjectDao.getOne(subjno)
+        return shopaccDao.findByShopid(shopId)
+                ?: throw TransactionProcessException(TradeErrorCode.SHOP_NOT_EXISTS, "商户<$shopId>不存在")
     }
 
     override fun readSubject(subjno: String): TSubject {
-        return subjectDao.getOne(subjno)
+        return subjectDao.findBySubjno(subjno)
+                ?: throw TransactionProcessException(TradeErrorCode.SUBJECT_NOT_EXISTS, "科目<$subjno>不存在")
     }
 
     override fun readTranstype(transtype: Int): TTranstype {
-        return transtypeDao.getOne(transtype)
+        return transtypeDao.findByTranstype(transtype)
+                ?: throw TransactionProcessException(TradeErrorCode.SUBJECT_NOT_EXISTS, "交易类型<$transtype>未配置")
     }
 }
 
@@ -96,26 +94,37 @@
 
 
     private fun getlockAccount(accno: String): TAccount {
-        //TODO 等待锁
-        return accountDao.getOne(accno)
+        return accountDao.getByAccnoForUpdate(accno)
+                ?: throw throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "账号<$accno>不存在")
     }
 
     private fun getlockAccountNowait(accno: String): TAccount {
-        //TODO 等待锁
-        return accountDao.getOne(accno)
+        return try {
+            accountDao.getByAccnoForUpdateNowait(accno)
+                    ?: throw throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "账号<$accno>不存在")
+        } catch (ex: Exception) {
+            when (ex) {
+                is CannotAcquireLockException, is LockTimeoutException -> throw TransactionException(TradeErrorCode.ACCOUNT_TRADE_BUSY, "账号<$accno>交易繁忙,请稍后再试")
+                else -> throw ex
+            }
+        }
     }
 
     private fun getLockUserdtlNowait(refno: String): TUserdtl {
-        userdtlDao.findByRefnoForUpdate(refno).let {
-            if (null != it) {
-                return it
+        return try {
+            userdtlDao.findByRefnoForUpdateNowait(refno)
+                    ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "交易参考号<$refno>不存在")
+        } catch (ex: Exception) {
+            when (ex) {
+                is CannotAcquireLockException, is LockTimeoutException -> throw TransactionException(TradeErrorCode.LOCK_READ_TIMEOUT, "交易参考号<$refno>被锁定,请稍后再试")
+                else -> throw ex
             }
-            throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "交易参考号<$refno>不存在")
         }
     }
 
     private fun getLockUserdtl(refno: String): TUserdtl {
         return userdtlDao.findByRefnoForUpdate(refno)
+                ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "交易参考号<$refno>不存在")
     }
 
     private fun checkOuttradenoExist(outtradeno: String): Boolean {
@@ -135,7 +144,6 @@
         if (!overdraft && account.checkOverdraft())
             throw TransactionProcessException(TradeErrorCode.SHORT_BALANCE_ERROR, "账户<$accno>余额不足")
 
-        account.tac = account.generateTac()
         return accountDao.save(account) //入库更新
     }
 
diff --git a/src/main/kotlin/com/supwisdom/dlpay/consume/service/pay_service.kt b/src/main/kotlin/com/supwisdom/dlpay/consume/service/pay_service.kt
index 7bf801e..0c77e4c 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/consume/service/pay_service.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/consume/service/pay_service.kt
@@ -6,16 +6,19 @@
 import com.supwisdom.dlpay.framework.domain.TShopacc
 import com.supwisdom.dlpay.framework.domain.TSubject
 import com.supwisdom.dlpay.framework.domain.TTranstype
+import org.springframework.transaction.annotation.Propagation
+import org.springframework.transaction.annotation.Transactional
 
 interface AccountUtilServcie {
 
-    fun readAccountForUpdate(userid: String, nowait: Boolean): TAccount
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class))
+    fun readAccountForUpdateNowait(userid: String): TAccount
+
+
     fun readAccount(userid: String): TAccount
 
-    fun readShopAccForUpdate(shopId: Int, nowait: Boolean): TShopacc
     fun readShopAcc(shopId: Int): TShopacc
 
-    fun readSubjectForUpdate(subjno: String, nowait: Boolean): TSubject
     fun readSubject(subjno: String): TSubject
 
     fun readTranstype(transtype: Int): TTranstype
@@ -26,18 +29,22 @@
     /**
      * 一步完成交易
      */
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class))
     fun process(builder: PersonTransBuilder): TUserdtl
 
     /**
      * 两步交易,交易初始化方法,检查交易参数,记录交易流水
      */
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class))
     fun init(builder: PersonTransBuilder): TUserdtl
 
     /**
      * 两步交易,完成交易过程,包括更新交易状态(成功、失败),更新借贷双方余额
      */
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class))
     fun finish(paydtl: TUserdtl, status: String, businessData: Map<String, String>?): TUserdtl
 
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class))
     fun finish(refno: String, status: String, businessData: Map<String, String>?): TUserdtl
 
     /**
@@ -45,9 +52,10 @@
      * 如果交易记录被锁,立刻抛出异常
      * @throws TransactionProcessException
      */
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class))
     fun wip(paydtl: TUserdtl): TUserdtl
 
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class))
     fun wip(refno: String): TUserdtl
 
-
 }
\ No newline at end of file