解决方案 »

  1.   

    楼主可以考虑下用aop控制下,在这些方法上加锁或者类似锁的机制。
    或者在获得A的锁后验证数据库条件,得不到锁的话就进入等待状态,释放先前得到的锁。
      

  2.   


    方法a是一个生成单号的方法, 单号需要连续.
    如果事务单独控制, 那么方法b如果出现回滚(b的业务回滚), 方法a也要回滚. 且c方法可能已经在a回滚前的基础上进行了操作(因为a是单独事务),所以方法b回滚后, a方法还不能回滚,只能将b中用掉的单号单独保存,建立废号再利用机制.这个改动貌似会更大.
      

  3.   


    方法a是一个生成单号的方法, 单号需要连续.
    如果事务单独控制, 那么方法b如果出现回滚(b的业务回滚), 方法a也要回滚. 且c方法可能已经在a回滚前的基础上进行了操作(因为a是单独事务),所以方法b回滚后, a方法还不能回滚,只能将b中用掉的单号单独保存,建立废号再利用机制.这个改动貌似会更大.
    你的意思是你十个操作只要有一个失败十个都要回滚, 如果是这样的话那么你的问题不是死锁的问题, 就算程序中不出现死锁, 线程1执行5次a方法, 线程2执行1次a方法, 线程1再执行5次a方法并且失败了, 那么就算不存在死锁仍然会存在你现在说的无法回滚的问题, 而你所说的解决方案在b和c方法上加锁也是不现实的, 这样相当于将事务序列化执行, 并发性能是无法容忍的, 所以你的这个问题本身从设计上就是不对的, 一个批量处理, 相当于多次单条的处理, 每次成功就提交事务, 就算有失败的也不是全部回滚, 而应该最后提示: 成功xxx条, 失败xxx条
      

  4.   


    方法a是一个生成单号的方法, 单号需要连续.
    如果事务单独控制, 那么方法b如果出现回滚(b的业务回滚), 方法a也要回滚. 且c方法可能已经在a回滚前的基础上进行了操作(因为a是单独事务),所以方法b回滚后, a方法还不能回滚,只能将b中用掉的单号单独保存,建立废号再利用机制.这个改动貌似会更大.
    你的意思是你十个操作只要有一个失败十个都要回滚, 如果是这样的话那么你的问题不是死锁的问题, 就算程序中不出现死锁, 线程1执行5次a方法, 线程2执行1次a方法, 线程1再执行5次a方法并且失败了, 那么就算不存在死锁仍然会存在你现在说的无法回滚的问题, 而你所说的解决方案在b和c方法上加锁也是不现实的, 这样相当于将事务序列化执行, 并发性能是无法容忍的, 所以你的这个问题本身从设计上就是不对的, 一个批量处理, 相当于多次单条的处理, 每次成功就提交事务, 就算有失败的也不是全部回滚, 而应该最后提示: 成功xxx条, 失败xxx条是的.目前的解决办法是将批处理中的每条作为单独事务了. 但是引发了另外一个问题. 在某个方法d中, 需要生成2个单据号(一次操作,生成2张单据). 调用了2次方法a, 这种因为必须保证d在一个事务中,这样就也可能会存在上面说的问题. 请问这种情况怎么解决呢?
      

  5.   


    方法a是一个生成单号的方法, 单号需要连续.
    如果事务单独控制, 那么方法b如果出现回滚(b的业务回滚), 方法a也要回滚. 且c方法可能已经在a回滚前的基础上进行了操作(因为a是单独事务),所以方法b回滚后, a方法还不能回滚,只能将b中用掉的单号单独保存,建立废号再利用机制.这个改动貌似会更大.
    你的意思是你十个操作只要有一个失败十个都要回滚, 如果是这样的话那么你的问题不是死锁的问题, 就算程序中不出现死锁, 线程1执行5次a方法, 线程2执行1次a方法, 线程1再执行5次a方法并且失败了, 那么就算不存在死锁仍然会存在你现在说的无法回滚的问题, 而你所说的解决方案在b和c方法上加锁也是不现实的, 这样相当于将事务序列化执行, 并发性能是无法容忍的, 所以你的这个问题本身从设计上就是不对的, 一个批量处理, 相当于多次单条的处理, 每次成功就提交事务, 就算有失败的也不是全部回滚, 而应该最后提示: 成功xxx条, 失败xxx条是的.目前的解决办法是将批处理中的每条作为单独事务了. 但是引发了另外一个问题. 在某个方法d中, 需要生成2个单据号(一次操作,生成2张单据). 调用了2次方法a, 这种因为必须保证d在一个事务中,这样就也可能会存在上面说的问题. 请问这种情况怎么解决呢?
    这样的需求只能做成序列化事务, d方法和a方法公用一个锁
      

  6.   

    你的A方法的逻辑就是生成连续的单号?
    那用一个sequence不就解决问题了么。 干嘛搞这么复杂。
      

  7.   

    解决办法如下:
    问题一:批量处理.
          解决方法:将批量处理中每单条一个事务.
    问题二.一个事务操作中需要2个单号,调用2次方法a
          解决方法:新增方法d,生成指定数量的单号. 应用层a,d写锁互斥,数据库层用悲观锁锁行