0

I want to add some dummy data in a table using Spring MVC.

Here is the code:-

In Dao

    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;
}

This generates a dummy value to be added to an integer column in the table. Basically if the table is empty it generates 80001 or if not then increment the existing maximum value. Kindly note that I cannot make the column unique because of some requirement constraint. After I get the data from the above function, I just insert it in the table using the merge function.

 entityManager.merge(entity);

Now the problem is that when multiple users hit the generate function at the same time, they are assigned the same data and this causes duplicacy when the data is pushed to the table by different clients. How do I prevent this duplicacy?

Edit..

1, I have already tried the java synchronized keyword on my generate method and it doesn't work, maybe because I'm using the spring's transactional in my service layer.

2, I cannot use database sequence to generate unique data, the data has to come from the generate method.

2 Answers2

1

Its not the problem of Spring MVC data duplicacy issue. Your application needs to prevent the data duplicacy by controlling concurrent access to the method which is generating id's (or) preferred way is to use a database sequence to get the next id instead of application generating the id.

If you can't use a database sequence and still want to use generate method then your application need to control the concurrency either by adding JAVA synchronized keyword to generate method (and/or) lock any object to allow single thread access to the method. This will make other users/threads to wait until this method is executed.

Anudeep Gade
  • 1,365
  • 1
  • 9
  • 18
  • The java synchronized keyword didn't work for me. Maybe because I'm using the spring transactional service. I have edited my original question to include this piece of info – Dhruv Pant Jun 12 '16 at 04:55
  • Did you try to keep whole generate method in a synchronized block like this public int generateData(){ synchronized { ..... } } – Anudeep Gade Jun 13 '16 at 09:09
  • yes, I kept the whole generate method in the synchronized block – Dhruv Pant Jun 14 '16 at 04:26
  • Try to lock any object - see here http://stackoverflow.com/questions/5476825/limiting-concurrent-access-to-a-method – Anudeep Gade Jun 14 '16 at 11:47
1

Have a look at the @Version annotation in hibernate. It might solve your problem.

Or, what you can do is using pessimistic locking and locking your table when performing operations.

Shervin Asgari
  • 23,901
  • 30
  • 103
  • 143
  • Thanks Shervin, however I'm not concerned about updating the same record, I'm just inserting multiple records simultaneously, therefore I doubt the optimistic locking would help me in this case. Kndly correct me if I'm wrong.. – Dhruv Pant Jun 14 '16 at 07:08
  • Is your read and write in the same transaction? Hibernate will not write to the database until after the transactional method is finished. So you need to make sure your transactions also match how you are writing/reading to the database. Its better to use Locks, and not synchronized. ie: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/ReentrantLock.html – Shervin Asgari Jun 14 '16 at 13:56
  • My generate method which reads the database and generates the data to be written and the actual write method are in different transactions.. – Dhruv Pant Jun 21 '16 at 06:23