Updated Branches: refs/heads/master 6d86af85b -> ab5ea3feb
CLOUDSTACK-4133 Introduce a global lock on template and pool id so that concurrent threads wont be inserting the same row in DB and hit MySQLIntegrityConstraintViolationException Signed off by : nitin mehta<nitin.me...@citrix.com> Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ab5ea3fe Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ab5ea3fe Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ab5ea3fe Branch: refs/heads/master Commit: ab5ea3febd9cc499b1cac024306cad947a9916de Parents: 6d86af8 Author: Nitin Mehta <nitin.me...@citrix.com> Authored: Fri Aug 9 13:43:46 2013 +0530 Committer: Nitin Mehta <nitin.me...@citrix.com> Committed: Fri Aug 9 14:03:43 2013 +0530 ---------------------------------------------------------------------- .../storage/datastore/PrimaryDataStoreImpl.java | 42 ++++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ab5ea3fe/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java ---------------------------------------------------------------------- diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index b20d534..e02d9bc 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -23,6 +23,7 @@ import java.util.List; import javax.inject.Inject; +import com.cloud.utils.db.GlobalLock; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; @@ -225,18 +226,43 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { public DataObject create(DataObject obj) { // create template on primary storage if (obj.getType() == DataObjectType.TEMPLATE) { - VMTemplateStoragePoolVO templateStoragePoolRef = templatePoolDao.findByPoolTemplate(this.getId(), - obj.getId()); - if (templateStoragePoolRef == null) { + try{ + String templateIdPoolIdString = "templateId:" + obj.getId() + "poolId:" + this.getId(); + VMTemplateStoragePoolVO templateStoragePoolRef; + GlobalLock lock = GlobalLock.getInternLock(templateIdPoolIdString); + if (!lock.lock(5)) { + s_logger.debug("Couldn't lock the db on the string " + templateIdPoolIdString); + return null; + } try { - templateStoragePoolRef = new VMTemplateStoragePoolVO(this.getId(), obj.getId()); - templateStoragePoolRef = templatePoolDao.persist(templateStoragePoolRef); - } catch (Throwable t) { - templateStoragePoolRef = templatePoolDao.findByPoolTemplate(this.getId(), obj.getId()); + templateStoragePoolRef = templatePoolDao.findByPoolTemplate(this.getId(), + obj.getId()); if (templateStoragePoolRef == null) { - throw new CloudRuntimeException("Failed to create template storage pool entry"); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Not found (" + templateIdPoolIdString + ") in template_spool_ref, persisting it"); + } + templateStoragePoolRef = new VMTemplateStoragePoolVO(this.getId(), obj.getId()); + templateStoragePoolRef = templatePoolDao.persist(templateStoragePoolRef); } + } catch (Throwable t) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Failed to insert (" + templateIdPoolIdString + ") to template_spool_ref", t); + } + templateStoragePoolRef = templatePoolDao.findByPoolTemplate(this.getId(), obj.getId()); + if (templateStoragePoolRef == null) { + throw new CloudRuntimeException("Failed to create template storage pool entry"); + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Another thread already inserts " + templateStoragePoolRef.getId() + " to template_spool_ref", t); + } + } + }finally { + lock.unlock(); + lock.releaseRef(); } + } catch (Exception e){ + s_logger.debug("Caught exception ", e); } } else if (obj.getType() == DataObjectType.SNAPSHOT) { return objectInStoreMgr.create(obj, this);