Spring &引用;同步的;招标交易系统
我尝试使用Grails2.1(Hibernate和Spring)实现一个投标系统,实现了一个BidService的以下“幼稚”实现 但它似乎无法阻止提高条件,这导致来自不同并发用户的“重复”出价 一些信息: -默认情况下,BidService是事务性的, -项目和投标模型使用“版本:错误”(悲观锁定) 但正如9.2范围服务中所述: 默认情况下,对服务方法的访问是不同步的,因此没有什么可以阻止这些方法的并发执行。事实上,由于服务是单例的,并且可以并发使用,所以在存储服务中的状态时应该非常小心。或者走简单(更好)的路,永远不要在服务中存储状态 我曾想过在整个processBid()方法中使用“synchronized”,但这听起来相当粗鲁,可能会引起活跃度问题或死锁。 另一方面,以异步方式处理竞价,可以防止直接向用户发送有关竞价胜负的反馈 在这种情况下,您有什么建议或最佳做法吗Spring &引用;同步的;招标交易系统,spring,hibernate,grails,concurrency,synchronized,Spring,Hibernate,Grails,Concurrency,Synchronized,我尝试使用Grails2.1(Hibernate和Spring)实现一个投标系统,实现了一个BidService的以下“幼稚”实现 但它似乎无法阻止提高条件,这导致来自不同并发用户的“重复”出价 一些信息: -默认情况下,BidService是事务性的, -项目和投标模型使用“版本:错误”(悲观锁定) 但正如9.2范围服务中所述: 默认情况下,对服务方法的访问是不同步的,因此没有什么可以阻止这些方法的并发执行。事实上,由于服务是单例的,并且可以并发使用,所以在存储服务中的状态时应该非常小心。或者
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
}
}