Java 如何保存表的顺序并防止并发问题

Java 如何保存表的顺序并防止并发问题,java,database,spring,hibernate,jpa,Java,Database,Spring,Hibernate,Jpa,我有以下问题,我必须保存表中某些元素的顺序。这是通过订单号完成的。所以第一个元素有订单1,第十个元素有订单10,等等。我还保存了一个品牌值,这意味着订单只在一个品牌的所有行内。 我的配置是Spring3.1,带有Hibernate4.1.6和Spring数据,我还使用JPA接口,底层是Mysql数据库 我现在有一个save方法,它通过namedquery获得最大值。然后将该值增加1。现在使用对象设置器设置值。然后保存它 if(tag.getOrdering()==0) {

我有以下问题,我必须保存表中某些元素的顺序。这是通过订单号完成的。所以第一个元素有订单1,第十个元素有订单10,等等。我还保存了一个品牌值,这意味着订单只在一个品牌的所有行内。 我的配置是Spring3.1,带有Hibernate4.1.6和Spring数据,我还使用JPA接口,底层是Mysql数据库

我现在有一个save方法,它通过namedquery获得最大值。然后将该值增加1。现在使用对象设置器设置值。然后保存它

    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() 但这不起作用,我的连接总是只读的readonly=false标志设置不正确,我没有发现什么地方出了问题。我也认为这不能解决我的问题

然后我尝试使用@Version属性,但这不起作用,因为我不使用一个对象实例。这两个线程在两个不同的行上工作,因此版本控制不能解决问题

现在我看到四种不同的方法

首先:我可以在代码中使用同步锁对象,让一个线程等待另一个线程释放对象上的锁

第二:我可以获得一个完整的表锁,我不知道如何使用hibernate,而且它看起来太大了,无法阻止整个表

第三:当我没有品牌栏,里面的订单可能是相同的,我可以添加一个独特的约束,这将抛出一个异常,我可以使用它再次递增,直到它工作

第四:现在我找到了另一种可行的方法。我没有保存订购号码。相反,我添加了一列,其中包含顺序中下一个元素的id。这意味着每个请求中都有一个顺序连接,但是我知道这个表没有很多行,所以性能并不重要。此外,订单更改时的更新也会容易得多

那么,解决这个问题的正确方法是什么呢。我还必须解决当顺序改变时必须更新所有对象的问题

你试过了吗?JPA提供者的业务是如何在有序列表的情况下处理并发性(我考虑的是一些限制)。有序树结构的示例

您也可以尝试使用。请参阅以了解悲观的

您尝试过吗?JPA提供者的业务是如何在有序列表的情况下处理并发性(我考虑的是一些限制)。有序树结构的示例


您也可以尝试使用。请参阅,了解悲观的

使用mysql触发器应该允许您执行非常直接的检查另一个。

使用mysql触发器应该允许您执行非常直接的检查另一个。

我的问题的另一个解决方案是使order列和brand列都是唯一的(添加约束唯一性(订单、品牌))。然后,在特定品牌中可能只有一个订单号。然后,我必须对ConstraintViolationException作出反应,并使用新值重新插入。但我感谢这不是很好,因为您不知道ConstraintViolationException是否真的是由于唯一约束或其他一些约束冲突造成的

我的问题的另一个解决方案是使order列和brand列都是唯一的(addconstraint UNIQUE(order,brand))。然后,在特定品牌中可能只有一个订单号。然后,我必须对ConstraintViolationException作出反应,并使用新值重新插入。但我感谢这不是很好,因为您不知道ConstraintViolationException是否真的是由于唯一约束或其他一些约束冲突造成的你需要数据库事务,其他一切都是一个糟糕的解决办法。我建议你重新表述你的问题,说明如何让事务在你的环境中工作。我使用mysql,但我理解提供的隔离级别(读取未限制、读取可重复、序列化、读取提交)总是有行锁定。当我处理两个不同的行并通过从表中选择max(排序)来获得最大值时,即使隔离级别也不会阻止两次并发读取,因为正如我所看到的,读取不在特定行上(但我现在对它的理解也很差)您需要DB事务,其他一切都是一个糟糕的解决方法。我建议您重新表述一下如何在您的环境中进行事务处理的问题。我使用mysql,但据我所知,提供的隔离级别(读取未限制、读取可重复、可序列化、读取提交)总是有行锁定。当我处理两个不同的行并通过从表中选择max(排序)来获得最大值时,即使隔离级别也不会阻止两次并发读取,因为正如我所看到的,读取不在特定行上(但我现在对它的理解也很差)阅读@ordercolumn的文档在我看来,这只能用于另一个域对象内的列表,而不能用于域对象本身。jpa锁使imho行锁定,im在两个不同的行上工作,并在select max(值)上读取从表中。我需要jpa锁没有提供的表锁定阅读@ordercolumn的文档,在我看来,这只能用于另一个域对象内的列表,而不是域对象本身。jpa锁使imho行锁定,im在两个不同的r上工作