我有以下问题我必须保存表格中某些元素的顺序。这是通过订单号完成的。所以第一个元素有 ordering 1,第十个有 ordering 10 等等。我还保存了一个品牌价值,这意味着订购只在一个品牌的所有行内。我的配置是 Spring 3.1 和 Hibernate 4.1.6 和 Spring Data,我也使用 JPA 接口,底层是一个 Mysql 数据库。
我现在有一个保存方法,它通过命名查询获取最大值。然后将该值加一。现在使用对象设置器设置值。然后保存它。
if(tag.getOrdering()==0) {
int newOrderingNumber = tagRepository.getMaximumOrderingNumber();
newOrderingNumber++;
if(LOGGER.isDebugEnabled()) {
LOGGER.debug("Next Ordering Number for Tag is " + newOrderingNumber);
}
tag.setOrdering(newOrderingNumber);
}
在这里,我有一个问题,如果两个线程同时执行此操作会发生什么。他们都会保存相同的价值。但是必须增加两次。我的问题是如何防止这种情况发生。首先,我尝试对 spring 事务的隔离级别做一些事情,但 JPA 不知道事务级别以及我发现如何扩展 jpadialect 的方法,例如这里(http://amitstechblog.wordpress.com/2011/05/31 /supporting-custom-isolation-levels-with-jpa/)但这不起作用,我的 Connection 始终是只读的 readOnly=false 标志设置不正确,我没有找出问题所在。我也认为这不会解决我的问题。
然后我尝试使用@Version 属性,但这不起作用,因为我不在一个对象实例上工作。这两个线程在两个不同的行上工作,所以版本控制不能解决问题。
所以现在我看到了四种不同的方法。
第一:我可以在我的代码中使用同步锁对象,让一个线程等待另一个线程释放对象上的锁
第二:我可以获得一个全表锁,我不知道如何使用休眠模式,而且它似乎也太大了,无法阻止整个表。
第三:当我没有排序可能相同的品牌列时,我可以添加一个唯一约束,该约束将抛出一个异常,我可以使用它再次增加它,直到它起作用。
第四:现在我找到了另一种可行的方法。我不保存订购号。相反,我添加一列,其中包含按顺序排列的下一个元素的 id。这意味着每个请求中都有一个带有订单的 Join,但我知道这个表没有很多行,所以性能并不重要。此外,订单更改时的更新也会容易得多。
那么解决这个问题的正确方法是什么。当更改顺序时必须更新所有对象时,我还必须解决该问题。