我嘗試使用Grails 2.1(所以Hibernate和Spring) 以下「Bidish」實現bidging服務,但它似乎無法防止引發條件和這個結果在來自不同併發用戶的「重複」出價中。投標系統的「同步」交易
一對夫婦的信息: - BidService是事務默認情況下, - 項目和報價模型使用 「版本:假」(悲觀鎖)
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
}
}
但隨着http://grails.org/doc/latest/guide/services.html 9.2作用域服務聲明: 默認情況下,對服務方法的訪問不同步,因此沒有任何東西阻止這些方法的併發執行。實際上,因爲服務是單例,並且可以同時使用,所以在服務中存儲狀態時應該非常小心。或者走簡單(更好)的道路,不要在服務中存儲狀態。
我想在整個processBid()方法上使用「synchronized」,但這聽起來很粗魯,可能會引發活性問題或死鎖。另一方面,以異步方式處理投標,可阻止直接向用戶反饋關於贏/放拍賣的反饋。
在這種情況下使用任何建議或最佳做法? PS:我已經問過grails ML,但它是一個相當寬泛的Java併發問題。
驗證步驟需要一些時間並涉及狀態:項目的當前價格,其他出價,動態出價,... 因此,如果碰巧有兩個同時驗證(向右)爲兩個用戶設置出價,將導致重複出價值。我將尋求獨特的方法,即使它意味着在處理動態投標時改變一些邏輯,似乎也會更好。 你可能是正確的版本:錯誤我會檢查文檔。 – Wavyx
version:false會關閉樂觀鎖定,但要使用悲觀鎖定,您需要明確調用item.lock()http://grails.org/doc/latest/guide/GORM.html#locking 我將再次測試,但它是可能更適合獨特的限制 – Wavyx