"脏处理" 这里我说的意思 是这样的:
    在业务里扣费的时候,我查询到用户余额剩下100,然后我这里需要判断用户余额是否足够支付我需要扣的钱,例如我需要扣50;
但是,与此同时另一个业务也在进行另一个业务,需要扣60,如果两个操作并发,就有可能造成判断余额是否充足的时候都显示余额是够的,但是却会把余额扣到负数,如果业务决不允许余额低于0,这种最好用什么方案处理呢?
    如果不使用存储过程,也不给表加锁,同时也不把查询和处理做成一个整块的事物,还有没有什么好的办法?

解决方案 »

  1.   

    不使用存储过程,也不给表加锁,同时也不把查询和处理做成一个整块的事物,这意味着不在数据库层面来进行互斥的判断
    那可以在Java代码中来互斥比如通过将判断与扣费的代码放在一个同步代码块中就可以实现
    public static byte[] block = new byte[1];
    public void pay(int x) {
    synchronized(block){
    int amout=.... //获取余额
    if (amount>x) {
    // 执行支付
    }
    }
    }
      

  2.   

    不使用存储过程,也不给表加锁,同时也不把查询和处理做成一个整块的事物,这意味着不在数据库层面来进行互斥的判断
    那可以在Java代码中来互斥比如通过将判断与扣费的代码放在一个同步代码块中就可以实现 public static byte[] block = new byte[1];
    public void pay(int x) {
    synchronized(block){
    int amout=.... //获取余额
    if (amount>x) {
    // 执行支付
    }
    }
    }
      

  3.   

    做法同上,不过不需要额外的locker,使用自身类就可以了
        public void pay(double x) {
            synchronized(this.getClass()){ //or XXX.class XXX是你的用户类名
               double d = getBalance(); //在这里再调用一次查询          
                if (d>x) { //判断余额确实大于支付金额才操作,否则可以抛出异常或终止
                    // 执行支付
                }
            }
        }
      

  4.   

      加上同步就行了 出入参数的object 就是你要操作的对象
      

  5.   

    update account set money=money-100 where money=200
      

  6.   


    这不是好办法,当业务发展,有多服务器的时候,这样的代码全部要重写。
    该用Transaction的地方就要用。
      

  7.   

    抱歉,这几天不能上网,谢谢各位的回复.
    现在情况有些变化了,除了存储过程不能用之外,好像只要效率高的话,都可以的.
    但是还是不太清楚到底哪种方式会更效率一些另外ticmy讲的
    update account set money=money-100 where money=200 具体是什么意思呢?
    把判断集成到sql语句里?这样的话就不能提前知道能不能支付了,需要支付了才知道?那sql返回和sql异常要怎么处理好些?
      

  8.   

    恩,感谢GuuJiang,我决定就采用你的建议的方法,确实比较方便!
    同时也感谢其他朋友的建议