天天看點

NC6 關于憑證接口的坑

昨天開始,幫一個老客戶處理通過接口儲存的憑證,憑證号會出現重複的問題。追了很深的代碼,從ws實體轉換,到憑證号生成和斷号處理。有兩個問題一定要處理完善,不然接口有問題。

1.生成憑證号。如果憑證号字段為空,調用系統憑證儲存元件時,系統會使用獨立事務,自動生成憑證号,邏輯就是根據賬簿,類型,期間在庫裡存有目前最大号,然後+1。為了防止并發時查詢值的時候重複,系統做法是,在同一個事務中,先執行一句update進行鎖表,然後查詢,補号,設值,跟新最大值,事務送出後,解鎖。期間如果有線程通路,由于表被鎖,在執行update時,會阻塞,是以每個線程查詢的最大值不會重複。如果發生異常,遠端調用會調用復原方法(VoucherNoFetch.addRollbackHook(voucher);),復原最大憑證号。

2.斷号儲存。如果憑證号字段不為空,且大于最大值,那麼它與最大值之間的數字,會存入斷号表,用于補号。

3.斷号問題。由于是接口調用,發生異常不會復原,最大值已經加大,而生成的憑證号也沒儲存為斷号,是以就會出現斷号問題。如果接口發生異常,我們将生成憑證号儲存為斷号,貌似可以解決斷号問題,但是又會出現重複問題。

4.重複問題。假設發生憑證号重複異常,憑證沒有儲存,基于上面的處理,會将這個重複的憑證号儲存為斷号。我們知道,在生成憑證号時,會優先補号,那麼這個重複的憑證号就會通過補号,變成重複的憑證号。

由于以上的原因,防止憑證号斷号,重複,在catch裡加一個判斷,如果初始憑證号為空(預設是int.min)并且異常時憑證号大于0時,将此憑證号儲存為斷号。最好最合理的方法是憑證号全由NC生成。

順便說一句,接口調用的時候也可以加動态鎖,也是在事務送出後會自動解鎖。