diff --git a/utils/src/com/cloud/utils/db/GenericDao.java b/utils/src/com/cloud/utils/db/GenericDao.java index 274288c21bd..392fbe418de 100755 --- a/utils/src/com/cloud/utils/db/GenericDao.java +++ b/utils/src/com/cloud/utils/db/GenericDao.java @@ -236,5 +236,7 @@ public interface GenericDao { boolean lockInLockTable(String id, int seconds); boolean unlockFromLockTable(String id); + + public K getRandomlyIncreasingNextInSequence(Class clazz, String name); } \ No newline at end of file diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java index 6302c6bd817..44bc699a7d6 100755 --- a/utils/src/com/cloud/utils/db/GenericDaoBase.java +++ b/utils/src/com/cloud/utils/db/GenericDaoBase.java @@ -182,9 +182,11 @@ public abstract class GenericDaoBase implements Gene Type t = getClass().getGenericSuperclass(); if (t instanceof ParameterizedType) { _entityBeanType = (Class)((ParameterizedType)t).getActualTypeArguments()[0]; - } else { + } else if (((Class)t).getGenericSuperclass() instanceof ParameterizedType) { _entityBeanType = (Class)((ParameterizedType)((Class)t).getGenericSuperclass()).getActualTypeArguments()[0]; - + } else { + _entityBeanType = (Class)((ParameterizedType) + ( (Class)((Class)t).getGenericSuperclass()).getGenericSuperclass()).getActualTypeArguments()[0]; } s_daoMaps.put(_entityBeanType, this); @@ -291,6 +293,14 @@ public abstract class GenericDaoBase implements Gene return s_seqFetcher.getNextSequence(clazz, tg); } + @Override @DB(txn=false) + public K getRandomlyIncreasingNextInSequence(final Class clazz, final String name) { + final TableGenerator tg = _tgs.get(name); + assert (tg != null) : "Couldn't find Table generator using " + name; + + return s_seqFetcher.getRandomNextSequence(clazz, tg); + } + @Override @DB(txn=false) public List lockRows(final SearchCriteria sc, final Filter filter, final boolean exclusive) { return search(sc, filter, exclusive, false); diff --git a/utils/src/com/cloud/utils/db/SequenceFetcher.java b/utils/src/com/cloud/utils/db/SequenceFetcher.java index d562cc0056e..9148f372831 100644 --- a/utils/src/com/cloud/utils/db/SequenceFetcher.java +++ b/utils/src/com/cloud/utils/db/SequenceFetcher.java @@ -20,6 +20,7 @@ package com.cloud.utils.db; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; @@ -48,11 +49,19 @@ public class SequenceFetcher { ExecutorService _executors; public T getNextSequence(Class clazz, TableGenerator tg) { - return getNextSequence(clazz, tg, null); + return getNextSequence(clazz, tg, null, false); } public T getNextSequence(Class clazz, TableGenerator tg, Object key) { - Future future = _executors.submit(new Fetcher(clazz, tg, key)); + return getNextSequence(clazz, tg, key, false); + } + + public T getRandomNextSequence(Class clazz, TableGenerator tg) { + return getNextSequence(clazz, tg, null, true); + } + + public T getNextSequence(Class clazz, TableGenerator tg, Object key, boolean isRandom) { + Future future = _executors.submit(new Fetcher(clazz, tg, key, isRandom)); try { return future.get(); } catch (Exception e) { @@ -74,11 +83,13 @@ public class SequenceFetcher { TableGenerator _tg; Class _clazz; Object _key; + boolean isRandom = false; - protected Fetcher(Class clazz, TableGenerator tg, Object key) { + protected Fetcher(Class clazz, TableGenerator tg, Object key, boolean isRandom) { _tg = tg; _clazz = clazz; _key = key; + this.isRandom = isRandom; } @Override @SuppressWarnings("unchecked") @@ -103,7 +114,12 @@ public class SequenceFetcher { sql.append(" WHERE ").append(_tg.pkColumnName()).append("=?"); PreparedStatement updateStmt = txn.prepareStatement(sql.toString()); - updateStmt.setInt(2, _tg.allocationSize()); + if(isRandom){ + Random random = new Random(); + updateStmt.setInt(2, random.nextInt(10)); + } else { + updateStmt.setInt(2, _tg.allocationSize()); + } if (_key == null) { updateStmt.setString(3, _tg.pkColumnValue()); } else {