2016-06-10 111 views
0

我想使用Spring MVC在表中添加一些虚拟数据。Java防止并发访问Spring MVC中的方法

下面是代码: -

在道

public int generateData(){ 
    int iData = 80001; 
    String qry = "SELECT p FROM TestDomain p"; 
    List<TestDomain> runQry = daoHelper.findByQuery(qry); 
    if(runQry.size()!=0){ 
     TestDomain tdom = runQry.get((runQry.size()-1)); 
     iData = tdom.getNum_data(); 
     iData++; 
    } 


    return iData; 
} 

这产生要添加到表中的一个整数列的虚设值。基本上,如果表格是空的,它会生成80001,否则增加现有的最大值。请注意,由于某些需求限制,我无法使该列独一无二。从上述函数获取数据后,我只需使用合并函数将其插入表中。

entityManager.merge(entity); 

现在的问题是,当多个用户打在同一时间生成函数,它们分配相同的数据,这将导致duplicacy当数据被不同的客户推到桌子上。我如何防止这种重复?

编辑..

1,我已经尝试过在我的生成方法的Java synchronized关键字,它不工作,也许是因为我使用了Spring的事务,我的服务层。

2,我不能使用数据库序列来生成唯一的数据,数据必须来自生成方法。

回答

1

它不是Spring MVC数据重复问题的问题。您的应用程序需要通过控制对生成id(或)的方法的并发访问来防止数据重复,因为首选方法是使用数据库序列获取下一个id,而不是生成id的应用程序。

如果你不能使用数据库序列,并仍想使用生成方法,然后你的应用程序需要通过添加JAVA 同步关键字生成方法(和/或)锁定任何对象,允许单一控制并发或者线程访问该方法。这将使其他用户/线程等待,直到执行此方法。

+0

java synchronized关键字不适用于我。也许是因为我在使用spring事务服务。我已经编辑了我的原始问题以包含这条信息 –

+0

您是否尝试将整个生成方法保存在像这样的同步块中public int generateData(){synchronized {.....}} –

+0

是的,我保留了整个生成方法在同步块 –

1

看看hibernate中的@Version注解。它可能会解决你的问题。

或者,你可以做的是在执行操作时使用悲观锁定和锁定你的表。

+0

谢谢谢尔文,但我不关心更新相同的记录,我只是同时插入多个记录,因此我怀疑乐观锁定会帮助我在这种情况下。 Kndly纠正我,如果我错了.. –

+0

你的阅读和写在同一个交易?直到事务处理方法完成后,Hibernate才会写入数据库。所以你需要确保你的交易也符合你写/读数据库的方式。它更好地使用锁定,而不是同步。即:https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/ReentrantLock。html –

+0

我的生成方法读取数据库并生成要写入的数据和实际的写入方法在不同的事务中。 –