Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring &引用;同步的;招标交易系统_Spring_Hibernate_Grails_Concurrency_Synchronized - Fatal编程技术网

Spring &引用;同步的;招标交易系统

Spring &引用;同步的;招标交易系统,spring,hibernate,grails,concurrency,synchronized,Spring,Hibernate,Grails,Concurrency,Synchronized,我尝试使用Grails2.1(Hibernate和Spring)实现一个投标系统,实现了一个BidService的以下“幼稚”实现 但它似乎无法阻止提高条件,这导致来自不同并发用户的“重复”出价 一些信息: -默认情况下,BidService是事务性的, -项目和投标模型使用“版本:错误”(悲观锁定) 但正如9.2范围服务中所述: 默认情况下,对服务方法的访问是不同步的,因此没有什么可以阻止这些方法的并发执行。事实上,由于服务是单例的,并且可以并发使用,所以在存储服务中的状态时应该非常小心。或者

我尝试使用Grails2.1(Hibernate和Spring)实现一个投标系统,实现了一个BidService的以下“幼稚”实现 但它似乎无法阻止提高条件,这导致来自不同并发用户的“重复”出价

一些信息: -默认情况下,BidService是事务性的, -项目和投标模型使用“版本:错误”(悲观锁定)

但正如9.2范围服务中所述: 默认情况下,对服务方法的访问是不同步的,因此没有什么可以阻止这些方法的并发执行。事实上,由于服务是单例的,并且可以并发使用,所以在存储服务中的状态时应该非常小心。或者走简单(更好)的路,永远不要在服务中存储状态

我曾想过在整个processBid()方法中使用“synchronized”,但这听起来相当粗鲁,可能会引起活跃度问题或死锁。 另一方面,以异步方式处理竞价,可以防止直接向用户发送有关竞价胜负的反馈

在这种情况下,您有什么建议或最佳做法吗


PS:我已经问过grails ML,但这是一个相当广泛的Java并发性问题。

您的服务是无状态的,因此不需要同步,当它进入状态时需要同步

此外,您不需要再次使用任何锁定。。不更改现有状态,只添加新行。此外,我不是GORM专家,但是
version:false
应该从其名称中关闭乐观锁定,这并不意味着悲观锁定被激活


从您的问题中,我不明白您的问题是什么,但唯一的限制是防止数据库中的重复。

验证步骤需要一些时间,并且涉及状态:项目的当前价格、其他出价、动态出价。。。因此,如果恰好有2个同时验证(向右)为两个用户放置出价,将导致重复的出价值。我将研究独特的方法,它似乎更好,即使它意味着在处理动态出价时改变一些逻辑。关于version:false,您可能是对的。我将检查文档。version:false关闭乐观锁定,但要使用悲观锁定,您需要一个显式的调用项。lock()我将再次测试,但使用唯一约束可能更明智
class BidService{
  BidResult processBid(BidRequest bidRequest, Item item) throws BidException {
        // 1. Validation
        validateBid(bidRequest, item)   // -> throws BidException if bidRequest do not comply with bidding rules (price too low, invalid user, ...) 
       // 2. Proces Bid (we have some complex rules to process the bids too, but at the end we only place the bid
       Bid bid = placeBid(bidRequest, item)

       return bid
  }

   Bid placeBid(BidRequest bidRequest, Item item){
      // 1. Place Bid
      Bid bid = new Bid(bidRequest) // create a bid with the bidRequest values
      bid.save(flush: true, failOnError: true)

      // 2. Update Item price
      item.price = bid.value
      item.save(flush: true, failOnError: true)

      return bid      
   }
}