簡體   English   中英

如何保存表順序並防止並發問題

[英]How to save the order of a table and prevent concurrency issues

我有以下問題,我必須將某些元素的順序保存在表中。 這是通過訂單號完成的。 因此,第一個元素的排序為1,第十個元素的排序為10,依此類推。另外,我還保存了品牌價值,這意味着該排序僅在一個品牌的所有行中。 我的配置是帶有Hibernate 4.1.6和Spring Data的Spring 3.1,我也使用JPA接口,底層是Mysql數據庫。

我現在有一個save方法,該方法通過namedquery獲取最大值。 然后將值增加一。 現在,使用對象設置器設置值。 然后保存。

    if(tag.getOrdering()==0) {
        int newOrderingNumber = tagRepository.getMaximumOrderingNumber();
        newOrderingNumber++;
        if(LOGGER.isDebugEnabled()) {
            LOGGER.debug("Next Ordering Number for Tag is " + newOrderingNumber);
        }
        tag.setOrdering(newOrderingNumber);
    }

在這里,我有一個問題,如果兩個線程同時執行此操作會發生什么。 它們都將保存相同的值。 但是必須增加兩次。 我的問題是如何防止這種情況。 首先,我嘗試對春季交易的隔離級別做一些事情,但是JPA確實了解交易級別以及我發現如何擴展jpadialect的方法,例如此處( http://amitstechblog.wordpress.com/2011/05/31 / supporting-custom-isolation-levels-with-jpa / ),但沒有奏效,我的Connection始終為只讀狀態,未正確設置readOnly = false標志,我也沒有發現問題所在。 我也認為這不會解決我的問題。

然后,我嘗試使用@Version屬性,但這不起作用,因為我不在一個對象實例上工作。 這兩個線程在兩個不同的行上工作,因此版本控制無法解決問題。

所以現在我看到了四種不同的方法。

第一:我可以在代碼中使用同步鎖對象,讓一個線程等待另一個線程釋放該對象上的鎖

第二:我可以獲得一個全表鎖,我不知道該如何使用休眠方式,並且它似乎也太大了,無法阻塞整個表。

第三:當我不會在其中有相同順序的brand列時,我可以添加一個Unique約束,該約束將拋出一個Exception,我可以使用該異常再次對其進行遞增,直到它起作用為止。

第四:現在我找到了另一種可行的方法。 我不保存訂購號。 相反,我添加了按順序包含下一個元素的ID的列。 這意味着每個請求中都包含一個Join順序,但是我知道該表沒有很多行,因此性能並不重要。 同樣,當訂單更改時更新將更加容易。

那么什么是解決這個問題的正確方法。 當更改順序時必須更新所有對象時,我也必須解決該問題。

使用mysql觸發器應該可以使您進行直接檢查其他SO問題

您是否嘗試過@OrderColumn 在有序列表的情況下如何處理並發是JPA提供者的業務(我在考慮一些約束)。 是有序樹結構的示例。

您也可以嘗試使用JPA鎖 PESSIMISTIC

解決我的問題的另一種方法是使order列和brand列都為UNIQUE(ADD CONSTRAINT UNIQUE(order,brand))。 那么在一個特定品牌內可能只有一個訂單號。 然后,我將不得不對ConstraintViolationException做出反應,並使用新值重做插入。 但我要感謝它不是很好,因為您不知道ConstrainViolationException是否真的是由於Unique約束或其他一些Constraint Violation造成的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM