Updated Branches: refs/heads/4.2 dacc4e1a4 -> 281abef0d
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/281abef0 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/281abef0 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/281abef0 Branch: refs/heads/4.2 Commit: 281abef0de67ddc5f93408deff7dcc1ba73dfbf9 Parents: dacc4e1 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 13:53:31 2013 +0530 ---------------------------------------------------------------------- .../storage/datastore/PrimaryDataStoreImpl.java | 49 +++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/281abef0/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 0432381..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,31 +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) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Not found (templateId: " + obj.getId() + ", poolId: " + this.getId() + ") in template_spool_ref"); + 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 { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Persisting (templateId: " + obj.getId() + ", poolId: " + this.getId() + ") to template_spool_ref"); - } - templateStoragePoolRef = new VMTemplateStoragePoolVO(this.getId(), obj.getId()); - templateStoragePoolRef = templatePoolDao.persist(templateStoragePoolRef); - } catch (Throwable t) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Failed to insert (templateId: " + obj.getId() + ", poolId: " + this.getId() + ") to template_spool_ref", 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"); - } else { + if (s_logger.isDebugEnabled()) { - s_logger.debug("Another thread already inserts " + templateStoragePoolRef.getId() + " to template_spool_ref", t); + 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);