NC6 关于凭证接口的坑

昨天开始,帮一个老客户处理通过接口保存的凭证,凭证号会出现重复的问题。追了很深的代码,从ws实体转换,到凭证号生成和断号处理。有两个问题一定要处理完善,不然接口有问题。
1.生成凭证号。如果凭证号字段为空,调用系统凭证保存组件时,系统会使用独立事务,自动生成凭证号,逻辑就是根据账簿,类型,期间在库里存有当前最大号,然后+1。为了防止并发时查询值的时候重复,系统做法是,在同一个事务中,先执行一句update进行锁表,然后查询,补号,设值,跟新最大值,事务提交后,解锁。期间如果有线程访问,由于表被锁,在执行update时,会阻塞,所以每个线程查询的最大值不会重复。如果发生异常,远程调用会调用回滚方法(VoucherNoFetch.addRollbackHook(voucher);),回滚最大凭证号。
2.断号储存。如果凭证号字段不为空,且大于最大值,那么它与最大值之间的数字,会存入断号表,用于补号。
3.断号问题。由于是接口调用,发生异常不会回滚,最大值已经加大,而生成的凭证号也没保存为断号,所以就会出现断号问题。如果接口发生异常,我们将生成凭证号保存为断号,貌似可以解决断号问题,但是又会出现重复问题。
4.重复问题。假设发生凭证号重复异常,凭证没有保存,基于上面的处理,会将这个重复的凭证号保存为断号。我们知道,在生成凭证号时,会优先补号,那么这个重复的凭证号就会通过补号,变成重复的凭证号。
由于以上的原因,防止凭证号断号,重复,在catch里加一个判断,如果初始凭证号为空(默认是int.min)并且异常时凭证号大于0时,将此凭证号保存为断号。最好最合理的方法是凭证号全由NC生成。

顺便说一句,接口调用的时候也可以加动态锁,也是在事务提交后会自动解锁。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值