You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ke...@apache.org on 2014/03/01 00:37:32 UTC

[12/33] git commit: updated refs/heads/master to 90262a8

 use lock table for locking


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/fed85813
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/fed85813
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/fed85813

Branch: refs/heads/master
Commit: fed85813e95c31c7159edc367426e9069749cc28
Parents: bfb7835
Author: Kelven Yang <ke...@gmail.com>
Authored: Mon Feb 10 15:35:03 2014 -0800
Committer: Kelven Yang <ke...@gmail.com>
Committed: Fri Feb 28 15:35:58 2014 -0800

----------------------------------------------------------------------
 .../com/cloud/vm/VirtualMachineManagerImpl.java | 647 ++++++++++---------
 .../com/cloud/storage/VolumeApiServiceImpl.java | 186 +++---
 .../vm/snapshot/VMSnapshotManagerImpl.java      | 144 +++--
 3 files changed, 526 insertions(+), 451 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fed85813/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index a99c5ce..457fad2 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -4417,36 +4417,40 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
             public Object[] doInTransaction(TransactionStatus status) {
                 VmWorkJobVO workJob = null;
 
-                _vmDao.lockRow(vm.getId(), true);
-                List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(VirtualMachine.Type.Instance,
-                        vm.getId(), VmWorkStart.class.getName());
-
-                if (pendingWorkJobs.size() > 0) {
-                    assert (pendingWorkJobs.size() == 1);
-                    workJob = pendingWorkJobs.get(0);
-                } else {
-                    workJob = new VmWorkJobVO(context.getContextId());
-
-                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                    workJob.setCmd(VmWorkStart.class.getName());
-
-                    workJob.setAccountId(callingAccount.getId());
-                    workJob.setUserId(callingUser.getId());
-                    workJob.setStep(VmWorkJobVO.Step.Starting);
-                    workJob.setVmType(VirtualMachine.Type.Instance);
-                    workJob.setVmInstanceId(vm.getId());
-                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
-
-                    // save work context info (there are some duplications)
-                    VmWorkStart workInfo = new VmWorkStart(callingUser.getId(), callingAccount.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER);
-                    workInfo.setPlan(planToDeploy);
-                    workInfo.setParams(params);
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(VirtualMachine.Type.Instance,
+                            vm.getId(), VmWorkStart.class.getName());
+
+                    if (pendingWorkJobs.size() > 0) {
+                        assert (pendingWorkJobs.size() == 1);
+                        workJob = pendingWorkJobs.get(0);
+                    } else {
+                        workJob = new VmWorkJobVO(context.getContextId());
+
+                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                        workJob.setCmd(VmWorkStart.class.getName());
+
+                        workJob.setAccountId(callingAccount.getId());
+                        workJob.setUserId(callingUser.getId());
+                        workJob.setStep(VmWorkJobVO.Step.Starting);
+                        workJob.setVmType(VirtualMachine.Type.Instance);
+                        workJob.setVmInstanceId(vm.getId());
+                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+
+                        // save work context info (there are some duplications)
+                        VmWorkStart workInfo = new VmWorkStart(callingUser.getId(), callingAccount.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER);
+                        workInfo.setPlan(planToDeploy);
+                        workInfo.setParams(params);
+                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    }
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
                 }
-
-                return new Object[] {workJob, new Long(workJob.getId())};
             }
         });
 
@@ -4467,37 +4471,41 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
         Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
             @Override
             public Object[] doInTransaction(TransactionStatus status) {
-                _vmDao.lockRow(vm.getId(), true);
+                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
 
-                List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                        vm.getType(), vm.getId(),
-                        VmWorkStop.class.getName());
-
-                VmWorkJobVO workJob = null;
-                if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-                    assert (pendingWorkJobs.size() == 1);
-                    workJob = pendingWorkJobs.get(0);
-                } else {
-                    workJob = new VmWorkJobVO(context.getContextId());
-
-                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                    workJob.setCmd(VmWorkStop.class.getName());
-
-                    workJob.setAccountId(account.getId());
-                    workJob.setUserId(user.getId());
-                    workJob.setStep(VmWorkJobVO.Step.Prepare);
-                    workJob.setVmType(VirtualMachine.Type.Instance);
-                    workJob.setVmInstanceId(vm.getId());
-                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
-
-                    // save work context info (there are some duplications)
-                    VmWorkStop workInfo = new VmWorkStop(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, cleanup);
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                try {
+                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                            vm.getType(), vm.getId(),
+                            VmWorkStop.class.getName());
+
+                    VmWorkJobVO workJob = null;
+                    if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+                        assert (pendingWorkJobs.size() == 1);
+                        workJob = pendingWorkJobs.get(0);
+                    } else {
+                        workJob = new VmWorkJobVO(context.getContextId());
+
+                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                        workJob.setCmd(VmWorkStop.class.getName());
+
+                        workJob.setAccountId(account.getId());
+                        workJob.setUserId(user.getId());
+                        workJob.setStep(VmWorkJobVO.Step.Prepare);
+                        workJob.setVmType(VirtualMachine.Type.Instance);
+                        workJob.setVmInstanceId(vm.getId());
+                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+
+                        // save work context info (there are some duplications)
+                        VmWorkStop workInfo = new VmWorkStop(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, cleanup);
+                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    }
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
                 }
-
-                return new Object[] {workJob, new Long(workJob.getId())};
             }
         });
 
@@ -4520,37 +4528,40 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
         Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
             @Override
             public Object[] doInTransaction(TransactionStatus status) {
-                _vmDao.lockRow(vm.getId(), true);
-
-                List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                        VirtualMachine.Type.Instance, vm.getId(),
-                        VmWorkReboot.class.getName());
-
-                VmWorkJobVO workJob = null;
-                if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-                    assert (pendingWorkJobs.size() == 1);
-                    workJob = pendingWorkJobs.get(0);
-                } else {
-                    workJob = new VmWorkJobVO(context.getContextId());
-
-                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                    workJob.setCmd(VmWorkReboot.class.getName());
-
-                    workJob.setAccountId(account.getId());
-                    workJob.setUserId(user.getId());
-                    workJob.setStep(VmWorkJobVO.Step.Prepare);
-                    workJob.setVmType(VirtualMachine.Type.Instance);
-                    workJob.setVmInstanceId(vm.getId());
-                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
-
-                    // save work context info (there are some duplications)
-                    VmWorkReboot workInfo = new VmWorkReboot(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, params);
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                            VirtualMachine.Type.Instance, vm.getId(),
+                            VmWorkReboot.class.getName());
+
+                    VmWorkJobVO workJob = null;
+                    if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+                        assert (pendingWorkJobs.size() == 1);
+                        workJob = pendingWorkJobs.get(0);
+                    } else {
+                        workJob = new VmWorkJobVO(context.getContextId());
+
+                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                        workJob.setCmd(VmWorkReboot.class.getName());
+
+                        workJob.setAccountId(account.getId());
+                        workJob.setUserId(user.getId());
+                        workJob.setStep(VmWorkJobVO.Step.Prepare);
+                        workJob.setVmType(VirtualMachine.Type.Instance);
+                        workJob.setVmInstanceId(vm.getId());
+                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+
+                        // save work context info (there are some duplications)
+                        VmWorkReboot workInfo = new VmWorkReboot(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, params);
+                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    }
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
                 }
-
-                return new Object[] {workJob, new Long(workJob.getId())};
             }
         });
 
@@ -4572,36 +4583,39 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
             @Override
             public Object[] doInTransaction(TransactionStatus status) {
 
-                _vmDao.lockRow(vm.getId(), true);
-
-                List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                        VirtualMachine.Type.Instance, vm.getId(),
-                        VmWorkMigrate.class.getName());
+                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                            VirtualMachine.Type.Instance, vm.getId(),
+                            VmWorkMigrate.class.getName());
 
-                VmWorkJobVO workJob = null;
-                if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-                    assert (pendingWorkJobs.size() == 1);
-                    workJob = pendingWorkJobs.get(0);
-                } else {
+                    VmWorkJobVO workJob = null;
+                    if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+                        assert (pendingWorkJobs.size() == 1);
+                        workJob = pendingWorkJobs.get(0);
+                    } else {
 
-                    workJob = new VmWorkJobVO(context.getContextId());
+                        workJob = new VmWorkJobVO(context.getContextId());
 
-                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                    workJob.setCmd(VmWorkMigrate.class.getName());
+                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                        workJob.setCmd(VmWorkMigrate.class.getName());
 
-                    workJob.setAccountId(account.getId());
-                    workJob.setUserId(user.getId());
-                    workJob.setVmType(VirtualMachine.Type.Instance);
-                    workJob.setVmInstanceId(vm.getId());
-                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                        workJob.setAccountId(account.getId());
+                        workJob.setUserId(user.getId());
+                        workJob.setVmType(VirtualMachine.Type.Instance);
+                        workJob.setVmInstanceId(vm.getId());
+                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                    // save work context info (there are some duplications)
-                    VmWorkMigrate workInfo = new VmWorkMigrate(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, dest);
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                        // save work context info (there are some duplications)
+                        VmWorkMigrate workInfo = new VmWorkMigrate(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, dest);
+                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    }
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
                 }
-                return new Object[] {workJob, new Long(workJob.getId())};
             }
         });
 
@@ -4622,37 +4636,38 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
         Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
             @Override
             public Object[] doInTransaction(TransactionStatus status) {
-
-                _vmDao.lockRow(vm.getId(), true);
-
-                List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                        VirtualMachine.Type.Instance, vm.getId(),
-                        VmWorkMigrateAway.class.getName());
-
-                VmWorkJobVO workJob = null;
-                if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-                    assert (pendingWorkJobs.size() == 1);
-                    workJob = pendingWorkJobs.get(0);
-                } else {
-
-                    workJob = new VmWorkJobVO(context.getContextId());
-
-                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                    workJob.setCmd(VmWorkMigrateAway.class.getName());
-
-                    workJob.setAccountId(account.getId());
-                    workJob.setUserId(user.getId());
-                    workJob.setVmType(VirtualMachine.Type.Instance);
-                    workJob.setVmInstanceId(vm.getId());
-                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
-
-                    // save work context info (there are some duplications)
-                    VmWorkMigrateAway workInfo = new VmWorkMigrateAway(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId);
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                            VirtualMachine.Type.Instance, vm.getId(),
+                            VmWorkMigrateAway.class.getName());
+
+                    VmWorkJobVO workJob = null;
+                    if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+                        assert (pendingWorkJobs.size() == 1);
+                        workJob = pendingWorkJobs.get(0);
+                    } else {
+                        workJob = new VmWorkJobVO(context.getContextId());
+
+                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                        workJob.setCmd(VmWorkMigrateAway.class.getName());
+
+                        workJob.setAccountId(account.getId());
+                        workJob.setUserId(user.getId());
+                        workJob.setVmType(VirtualMachine.Type.Instance);
+                        workJob.setVmInstanceId(vm.getId());
+                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+
+                        // save work context info (there are some duplications)
+                        VmWorkMigrateAway workInfo = new VmWorkMigrateAway(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId);
+                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    }
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
                 }
-                return new Object[] {workJob, new Long(workJob.getId())};
             }
         });
 
@@ -4677,37 +4692,40 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
             @Override
             public Object[] doInTransaction(TransactionStatus status) {
 
-                _vmDao.lockRow(vm.getId(), true);
-
-                List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                        VirtualMachine.Type.Instance, vm.getId(),
-                        VmWorkMigrateWithStorage.class.getName());
+                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                            VirtualMachine.Type.Instance, vm.getId(),
+                            VmWorkMigrateWithStorage.class.getName());
 
-                VmWorkJobVO workJob = null;
-                if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-                    assert (pendingWorkJobs.size() == 1);
-                    workJob = pendingWorkJobs.get(0);
-                } else {
+                    VmWorkJobVO workJob = null;
+                    if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+                        assert (pendingWorkJobs.size() == 1);
+                        workJob = pendingWorkJobs.get(0);
+                    } else {
 
-                    workJob = new VmWorkJobVO(context.getContextId());
+                        workJob = new VmWorkJobVO(context.getContextId());
 
-                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                    workJob.setCmd(VmWorkMigrate.class.getName());
+                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                        workJob.setCmd(VmWorkMigrate.class.getName());
 
-                    workJob.setAccountId(account.getId());
-                    workJob.setUserId(user.getId());
-                    workJob.setVmType(VirtualMachine.Type.Instance);
-                    workJob.setVmInstanceId(vm.getId());
-                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                        workJob.setAccountId(account.getId());
+                        workJob.setUserId(user.getId());
+                        workJob.setVmType(VirtualMachine.Type.Instance);
+                        workJob.setVmInstanceId(vm.getId());
+                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                    // save work context info (there are some duplications)
-                    VmWorkMigrateWithStorage workInfo = new VmWorkMigrateWithStorage(user.getId(), account.getId(), vm.getId(),
-                            VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, destHostId, volumeToPool);
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                        // save work context info (there are some duplications)
+                        VmWorkMigrateWithStorage workInfo = new VmWorkMigrateWithStorage(user.getId(), account.getId(), vm.getId(),
+                                VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, destHostId, volumeToPool);
+                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    }
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
                 }
-                return new Object[] {workJob, new Long(workJob.getId())};
             }
         });
 
@@ -4731,38 +4749,41 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
             @Override
             public Object[] doInTransaction(TransactionStatus status) {
 
-                _vmDao.lockRow(vm.getId(), true);
+                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                            VirtualMachine.Type.Instance, vm.getId(),
+                            VmWorkMigrateForScale.class.getName());
 
-                List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                        VirtualMachine.Type.Instance, vm.getId(),
-                        VmWorkMigrateForScale.class.getName());
+                    VmWorkJobVO workJob = null;
+                    if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+                        assert (pendingWorkJobs.size() == 1);
+                        workJob = pendingWorkJobs.get(0);
+                    } else {
 
-                VmWorkJobVO workJob = null;
-                if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-                    assert (pendingWorkJobs.size() == 1);
-                    workJob = pendingWorkJobs.get(0);
-                } else {
+                        workJob = new VmWorkJobVO(context.getContextId());
 
-                    workJob = new VmWorkJobVO(context.getContextId());
+                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                        workJob.setCmd(VmWorkMigrate.class.getName());
 
-                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                    workJob.setCmd(VmWorkMigrate.class.getName());
+                        workJob.setAccountId(account.getId());
+                        workJob.setUserId(user.getId());
+                        workJob.setVmType(VirtualMachine.Type.Instance);
+                        workJob.setVmInstanceId(vm.getId());
+                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                    workJob.setAccountId(account.getId());
-                    workJob.setUserId(user.getId());
-                    workJob.setVmType(VirtualMachine.Type.Instance);
-                    workJob.setVmInstanceId(vm.getId());
-                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                        // save work context info (there are some duplications)
+                        VmWorkMigrateForScale workInfo = new VmWorkMigrateForScale(user.getId(), account.getId(), vm.getId(),
+                                VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, dest, newSvcOfferingId);
+                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                    // save work context info (there are some duplications)
-                    VmWorkMigrateForScale workInfo = new VmWorkMigrateForScale(user.getId(), account.getId(), vm.getId(),
-                            VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, dest, newSvcOfferingId);
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    }
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
                 }
-
-                return new Object[] {workJob, new Long(workJob.getId())};
             }
         });
 
@@ -4785,38 +4806,41 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
             @Override
             public Object[] doInTransaction(TransactionStatus status) {
 
-                _vmDao.lockRow(vm.getId(), true);
+                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                            VirtualMachine.Type.Instance, vm.getId(),
+                            VmWorkStorageMigration.class.getName());
 
-                List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                        VirtualMachine.Type.Instance, vm.getId(),
-                        VmWorkStorageMigration.class.getName());
+                    VmWorkJobVO workJob = null;
+                    if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+                        assert (pendingWorkJobs.size() == 1);
+                        workJob = pendingWorkJobs.get(0);
+                    } else {
 
-                VmWorkJobVO workJob = null;
-                if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-                    assert (pendingWorkJobs.size() == 1);
-                    workJob = pendingWorkJobs.get(0);
-                } else {
+                        workJob = new VmWorkJobVO(context.getContextId());
 
-                    workJob = new VmWorkJobVO(context.getContextId());
+                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                        workJob.setCmd(VmWorkStorageMigration.class.getName());
 
-                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                    workJob.setCmd(VmWorkStorageMigration.class.getName());
+                        workJob.setAccountId(account.getId());
+                        workJob.setUserId(user.getId());
+                        workJob.setVmType(VirtualMachine.Type.Instance);
+                        workJob.setVmInstanceId(vm.getId());
+                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                    workJob.setAccountId(account.getId());
-                    workJob.setUserId(user.getId());
-                    workJob.setVmType(VirtualMachine.Type.Instance);
-                    workJob.setVmInstanceId(vm.getId());
-                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                        // save work context info (there are some duplications)
+                        VmWorkStorageMigration workInfo = new VmWorkStorageMigration(user.getId(), account.getId(), vm.getId(),
+                                VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, destPool.getId());
+                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                    // save work context info (there are some duplications)
-                    VmWorkStorageMigration workInfo = new VmWorkStorageMigration(user.getId(), account.getId(), vm.getId(),
-                            VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, destPool.getId());
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    }
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
                 }
-
-                return new Object[] {workJob, new Long(workJob.getId())};
             }
         });
 
@@ -4837,37 +4861,41 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
             @Override
             public Object[] doInTransaction(TransactionStatus status) {
 
-                _vmDao.lockRow(vm.getId(), true);
+                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
 
-                List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                        VirtualMachine.Type.Instance, vm.getId(),
-                        VmWorkAddVmToNetwork.class.getName());
+                try {
+                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                            VirtualMachine.Type.Instance, vm.getId(),
+                            VmWorkAddVmToNetwork.class.getName());
 
-                VmWorkJobVO workJob = null;
-                if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-                    assert (pendingWorkJobs.size() == 1);
-                    workJob = pendingWorkJobs.get(0);
-                } else {
+                    VmWorkJobVO workJob = null;
+                    if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+                        assert (pendingWorkJobs.size() == 1);
+                        workJob = pendingWorkJobs.get(0);
+                    } else {
 
-                    workJob = new VmWorkJobVO(context.getContextId());
+                        workJob = new VmWorkJobVO(context.getContextId());
 
-                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                    workJob.setCmd(VmWorkAddVmToNetwork.class.getName());
+                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                        workJob.setCmd(VmWorkAddVmToNetwork.class.getName());
 
-                    workJob.setAccountId(account.getId());
-                    workJob.setUserId(user.getId());
-                    workJob.setVmType(VirtualMachine.Type.Instance);
-                    workJob.setVmInstanceId(vm.getId());
-                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                        workJob.setAccountId(account.getId());
+                        workJob.setUserId(user.getId());
+                        workJob.setVmType(VirtualMachine.Type.Instance);
+                        workJob.setVmInstanceId(vm.getId());
+                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                    // save work context info (there are some duplications)
-                    VmWorkAddVmToNetwork workInfo = new VmWorkAddVmToNetwork(user.getId(), account.getId(), vm.getId(),
-                            VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, network.getId(), requested);
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                        // save work context info (there are some duplications)
+                        VmWorkAddVmToNetwork workInfo = new VmWorkAddVmToNetwork(user.getId(), account.getId(), vm.getId(),
+                                VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, network.getId(), requested);
+                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    }
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
                 }
-                return new Object[] {workJob, new Long(workJob.getId())};
             }
         });
 
@@ -4888,37 +4916,40 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
             @Override
             public Object[] doInTransaction(TransactionStatus status) {
 
-                _vmDao.lockRow(vm.getId(), true);
+                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                            VirtualMachine.Type.Instance, vm.getId(),
+                            VmWorkRemoveNicFromVm.class.getName());
 
-                List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                        VirtualMachine.Type.Instance, vm.getId(),
-                        VmWorkRemoveNicFromVm.class.getName());
+                    VmWorkJobVO workJob = null;
+                    if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+                        assert (pendingWorkJobs.size() == 1);
+                        workJob = pendingWorkJobs.get(0);
+                    } else {
 
-                VmWorkJobVO workJob = null;
-                if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-                    assert (pendingWorkJobs.size() == 1);
-                    workJob = pendingWorkJobs.get(0);
-                } else {
-
-                    workJob = new VmWorkJobVO(context.getContextId());
+                        workJob = new VmWorkJobVO(context.getContextId());
 
-                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                    workJob.setCmd(VmWorkRemoveNicFromVm.class.getName());
+                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                        workJob.setCmd(VmWorkRemoveNicFromVm.class.getName());
 
-                    workJob.setAccountId(account.getId());
-                    workJob.setUserId(user.getId());
-                    workJob.setVmType(VirtualMachine.Type.Instance);
-                    workJob.setVmInstanceId(vm.getId());
-                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                        workJob.setAccountId(account.getId());
+                        workJob.setUserId(user.getId());
+                        workJob.setVmType(VirtualMachine.Type.Instance);
+                        workJob.setVmInstanceId(vm.getId());
+                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                    // save work context info (there are some duplications)
-                    VmWorkRemoveNicFromVm workInfo = new VmWorkRemoveNicFromVm(user.getId(), account.getId(), vm.getId(),
-                            VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, nic.getId());
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                        // save work context info (there are some duplications)
+                        VmWorkRemoveNicFromVm workInfo = new VmWorkRemoveNicFromVm(user.getId(), account.getId(), vm.getId(),
+                                VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, nic.getId());
+                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    }
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
                 }
-                return new Object[] {workJob, new Long(workJob.getId())};
             }
         });
 
@@ -4939,37 +4970,40 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
             @Override
             public Object[] doInTransaction(TransactionStatus status) {
 
-                _vmDao.lockRow(vm.getId(), true);
-
-                List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                        VirtualMachine.Type.Instance, vm.getId(),
-                        VmWorkRemoveVmFromNetwork.class.getName());
+                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                            VirtualMachine.Type.Instance, vm.getId(),
+                            VmWorkRemoveVmFromNetwork.class.getName());
 
-                VmWorkJobVO workJob = null;
-                if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-                    assert (pendingWorkJobs.size() == 1);
-                    workJob = pendingWorkJobs.get(0);
-                } else {
+                    VmWorkJobVO workJob = null;
+                    if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+                        assert (pendingWorkJobs.size() == 1);
+                        workJob = pendingWorkJobs.get(0);
+                    } else {
 
-                    workJob = new VmWorkJobVO(context.getContextId());
+                        workJob = new VmWorkJobVO(context.getContextId());
 
-                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                    workJob.setCmd(VmWorkRemoveVmFromNetwork.class.getName());
+                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                        workJob.setCmd(VmWorkRemoveVmFromNetwork.class.getName());
 
-                    workJob.setAccountId(account.getId());
-                    workJob.setUserId(user.getId());
-                    workJob.setVmType(VirtualMachine.Type.Instance);
-                    workJob.setVmInstanceId(vm.getId());
-                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                        workJob.setAccountId(account.getId());
+                        workJob.setUserId(user.getId());
+                        workJob.setVmType(VirtualMachine.Type.Instance);
+                        workJob.setVmInstanceId(vm.getId());
+                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                    // save work context info (there are some duplications)
-                    VmWorkRemoveVmFromNetwork workInfo = new VmWorkRemoveVmFromNetwork(user.getId(), account.getId(), vm.getId(),
-                            VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, network, broadcastUri);
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                        // save work context info (there are some duplications)
+                        VmWorkRemoveVmFromNetwork workInfo = new VmWorkRemoveVmFromNetwork(user.getId(), account.getId(), vm.getId(),
+                                VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, network, broadcastUri);
+                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    }
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
                 }
-                return new Object[] {workJob, new Long(workJob.getId())};
             }
         });
 
@@ -4992,37 +5026,40 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
             @Override
             public Object[] doInTransaction(TransactionStatus status) {
 
-                _vmDao.lockRow(vm.getId(), true);
-
-                List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                        VirtualMachine.Type.Instance, vm.getId(),
-                        VmWorkReconfigure.class.getName());
+                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                            VirtualMachine.Type.Instance, vm.getId(),
+                            VmWorkReconfigure.class.getName());
 
-                VmWorkJobVO workJob = null;
-                if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-                    assert (pendingWorkJobs.size() == 1);
-                    workJob = pendingWorkJobs.get(0);
-                } else {
+                    VmWorkJobVO workJob = null;
+                    if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+                        assert (pendingWorkJobs.size() == 1);
+                        workJob = pendingWorkJobs.get(0);
+                    } else {
 
-                    workJob = new VmWorkJobVO(context.getContextId());
+                        workJob = new VmWorkJobVO(context.getContextId());
 
-                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                    workJob.setCmd(VmWorkReconfigure.class.getName());
+                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                        workJob.setCmd(VmWorkReconfigure.class.getName());
 
-                    workJob.setAccountId(account.getId());
-                    workJob.setUserId(user.getId());
-                    workJob.setVmType(VirtualMachine.Type.Instance);
-                    workJob.setVmInstanceId(vm.getId());
-                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                        workJob.setAccountId(account.getId());
+                        workJob.setUserId(user.getId());
+                        workJob.setVmType(VirtualMachine.Type.Instance);
+                        workJob.setVmInstanceId(vm.getId());
+                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                    // save work context info (there are some duplications)
-                    VmWorkReconfigure workInfo = new VmWorkReconfigure(user.getId(), account.getId(), vm.getId(),
-                            VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, newServiceOffering.getId(), reconfiguringOnExistingHost);
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                        // save work context info (there are some duplications)
+                        VmWorkReconfigure workInfo = new VmWorkReconfigure(user.getId(), account.getId(), vm.getId(),
+                                VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, newServiceOffering.getId(), reconfiguringOnExistingHost);
+                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    }
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
                 }
-                return new Object[] {workJob, new Long(workJob.getId())};
             }
         });
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fed85813/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index 1ee9286..184be38 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -2129,30 +2129,34 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
             public Object[] doInTransaction(TransactionStatus status) {
                 VmWorkJobVO workJob = null;
 
-                _vmInstanceDao.lockRow(vm.getId(), true);
-                workJob = new VmWorkJobVO(context.getContextId());
+                _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    workJob = new VmWorkJobVO(context.getContextId());
 
-                workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                workJob.setCmd(VmWorkAttachVolume.class.getName());
+                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                    workJob.setCmd(VmWorkAttachVolume.class.getName());
 
-                workJob.setAccountId(callingAccount.getId());
-                workJob.setUserId(callingUser.getId());
-                workJob.setStep(VmWorkJobVO.Step.Starting);
-                workJob.setVmType(VirtualMachine.Type.Instance);
-                workJob.setVmInstanceId(vm.getId());
-                workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                    workJob.setAccountId(callingAccount.getId());
+                    workJob.setUserId(callingUser.getId());
+                    workJob.setStep(VmWorkJobVO.Step.Starting);
+                    workJob.setVmType(VirtualMachine.Type.Instance);
+                    workJob.setVmInstanceId(vm.getId());
+                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                // save work context info (there are some duplications)
-                VmWorkAttachVolume workInfo = new VmWorkAttachVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId,
-                        deviceId);
-                workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                    // save work context info (there are some duplications)
+                    VmWorkAttachVolume workInfo = new VmWorkAttachVolume(callingUser.getId(), callingAccount.getId(), vm.getId(),
+                            VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, deviceId);
+                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-                AsyncJobVO jobVo = _jobMgr.getAsyncJob(workJob.getId());
-                s_logger.debug("New job " + workJob.getId() + ", result field: " + jobVo.getResult());
+                    AsyncJobVO jobVo = _jobMgr.getAsyncJob(workJob.getId());
+                    s_logger.debug("New job " + workJob.getId() + ", result field: " + jobVo.getResult());
 
-                return new Object[] {workJob, new Long(workJob.getId())};
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
+                }
             }
         });
 
@@ -2176,26 +2180,31 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
             public Object[] doInTransaction(TransactionStatus status) {
                 VmWorkJobVO workJob = null;
 
-                _vmInstanceDao.lockRow(vm.getId(), true);
-                workJob = new VmWorkJobVO(context.getContextId());
+                _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    workJob = new VmWorkJobVO(context.getContextId());
 
-                workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                workJob.setCmd(VmWorkDetachVolume.class.getName());
+                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                    workJob.setCmd(VmWorkDetachVolume.class.getName());
 
-                workJob.setAccountId(callingAccount.getId());
-                workJob.setUserId(callingUser.getId());
-                workJob.setStep(VmWorkJobVO.Step.Starting);
-                workJob.setVmType(VirtualMachine.Type.Instance);
-                workJob.setVmInstanceId(vm.getId());
-                workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                    workJob.setAccountId(callingAccount.getId());
+                    workJob.setUserId(callingUser.getId());
+                    workJob.setStep(VmWorkJobVO.Step.Starting);
+                    workJob.setVmType(VirtualMachine.Type.Instance);
+                    workJob.setVmInstanceId(vm.getId());
+                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                // save work context info (there are some duplications)
-                VmWorkDetachVolume workInfo = new VmWorkDetachVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId);
-                workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                    // save work context info (there are some duplications)
+                    VmWorkDetachVolume workInfo = new VmWorkDetachVolume(callingUser.getId(), callingAccount.getId(), vm.getId(),
+                            VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId);
+                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-                return new Object[] {workJob, new Long(workJob.getId())};
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
+                }
             }
         });
 
@@ -2220,27 +2229,32 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
             public Object[] doInTransaction(TransactionStatus status) {
                 VmWorkJobVO workJob = null;
 
-                _vmInstanceDao.lockRow(vm.getId(), true);
-                workJob = new VmWorkJobVO(context.getContextId());
+                _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+
+                try {
+                    workJob = new VmWorkJobVO(context.getContextId());
 
-                workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                workJob.setCmd(VmWorkResizeVolume.class.getName());
+                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                    workJob.setCmd(VmWorkResizeVolume.class.getName());
 
-                workJob.setAccountId(callingAccount.getId());
-                workJob.setUserId(callingUser.getId());
-                workJob.setStep(VmWorkJobVO.Step.Starting);
-                workJob.setVmType(VirtualMachine.Type.Instance);
-                workJob.setVmInstanceId(vm.getId());
-                workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                    workJob.setAccountId(callingAccount.getId());
+                    workJob.setUserId(callingUser.getId());
+                    workJob.setStep(VmWorkJobVO.Step.Starting);
+                    workJob.setVmType(VirtualMachine.Type.Instance);
+                    workJob.setVmInstanceId(vm.getId());
+                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                // save work context info (there are some duplications)
-                VmWorkResizeVolume workInfo = new VmWorkResizeVolume(callingUser.getId(), callingAccount.getId(), vm.getId(),
-                        VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, currentSize, newSize, newServiceOfferingId, shrinkOk);
-                workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                    // save work context info (there are some duplications)
+                    VmWorkResizeVolume workInfo = new VmWorkResizeVolume(callingUser.getId(), callingAccount.getId(), vm.getId(),
+                            VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, currentSize, newSize, newServiceOfferingId, shrinkOk);
+                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-                return new Object[] {workJob, new Long(workJob.getId())};
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
+                }
             }
         });
 
@@ -2265,27 +2279,31 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
             public Object[] doInTransaction(TransactionStatus status) {
                 VmWorkJobVO workJob = null;
 
-                _vmInstanceDao.lockRow(vm.getId(), true);
-                workJob = new VmWorkJobVO(context.getContextId());
+                _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    workJob = new VmWorkJobVO(context.getContextId());
 
-                workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                workJob.setCmd(VmWorkMigrateVolume.class.getName());
+                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                    workJob.setCmd(VmWorkMigrateVolume.class.getName());
 
-                workJob.setAccountId(callingAccount.getId());
-                workJob.setUserId(callingUser.getId());
-                workJob.setStep(VmWorkJobVO.Step.Starting);
-                workJob.setVmType(VirtualMachine.Type.Instance);
-                workJob.setVmInstanceId(vm.getId());
-                workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                    workJob.setAccountId(callingAccount.getId());
+                    workJob.setUserId(callingUser.getId());
+                    workJob.setStep(VmWorkJobVO.Step.Starting);
+                    workJob.setVmType(VirtualMachine.Type.Instance);
+                    workJob.setVmInstanceId(vm.getId());
+                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                // save work context info (there are some duplications)
-                VmWorkMigrateVolume workInfo = new VmWorkMigrateVolume(callingUser.getId(), callingAccount.getId(), vm.getId(),
-                        VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, destPoolId, liveMigrate);
-                workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                    // save work context info (there are some duplications)
+                    VmWorkMigrateVolume workInfo = new VmWorkMigrateVolume(callingUser.getId(), callingAccount.getId(), vm.getId(),
+                            VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, destPoolId, liveMigrate);
+                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-                return new Object[] {workJob, new Long(workJob.getId())};
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
+                }
             }
         });
 
@@ -2310,28 +2328,32 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
             public Object[] doInTransaction(TransactionStatus status) {
                 VmWorkJobVO workJob = null;
 
-                _vmInstanceDao.lockRow(vm.getId(), true);
-                workJob = new VmWorkJobVO(context.getContextId());
+                _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    workJob = new VmWorkJobVO(context.getContextId());
 
-                workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                workJob.setCmd(VmWorkTakeVolumeSnapshot.class.getName());
+                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                    workJob.setCmd(VmWorkTakeVolumeSnapshot.class.getName());
 
-                workJob.setAccountId(callingAccount.getId());
-                workJob.setUserId(callingUser.getId());
-                workJob.setStep(VmWorkJobVO.Step.Starting);
-                workJob.setVmType(VirtualMachine.Type.Instance);
-                workJob.setVmInstanceId(vm.getId());
-                workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                    workJob.setAccountId(callingAccount.getId());
+                    workJob.setUserId(callingUser.getId());
+                    workJob.setStep(VmWorkJobVO.Step.Starting);
+                    workJob.setVmType(VirtualMachine.Type.Instance);
+                    workJob.setVmInstanceId(vm.getId());
+                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                // save work context info (there are some duplications)
-                VmWorkTakeVolumeSnapshot workInfo = new VmWorkTakeVolumeSnapshot(
-                        callingUser.getId(), accountId != null ? accountId : callingAccount.getId(), vm.getId(),
-                        VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, policyId, snapshotId, quiesceVm);
-                workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                    // save work context info (there are some duplications)
+                    VmWorkTakeVolumeSnapshot workInfo = new VmWorkTakeVolumeSnapshot(
+                            callingUser.getId(), accountId != null ? accountId : callingAccount.getId(), vm.getId(),
+                            VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, policyId, snapshotId, quiesceVm);
+                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-                return new Object[] {workJob, new Long(workJob.getId())};
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
+                }
             }
         });
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fed85813/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
index 2fcbb48..4bae4d0 100644
--- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
+++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
@@ -863,27 +863,31 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
             public Object[] doInTransaction(TransactionStatus status) {
                 VmWorkJobVO workJob = null;
 
-                _vmInstanceDao.lockRow(vm.getId(), true);
-                workJob = new VmWorkJobVO(context.getContextId());
+                _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    workJob = new VmWorkJobVO(context.getContextId());
 
-                workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                workJob.setCmd(VmWorkCreateVMSnapshot.class.getName());
+                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                    workJob.setCmd(VmWorkCreateVMSnapshot.class.getName());
 
-                workJob.setAccountId(callingAccount.getId());
-                workJob.setUserId(callingUser.getId());
-                workJob.setStep(VmWorkJobVO.Step.Starting);
-                workJob.setVmType(VirtualMachine.Type.Instance);
-                workJob.setVmInstanceId(vm.getId());
-                workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                    workJob.setAccountId(callingAccount.getId());
+                    workJob.setUserId(callingUser.getId());
+                    workJob.setStep(VmWorkJobVO.Step.Starting);
+                    workJob.setVmType(VirtualMachine.Type.Instance);
+                    workJob.setVmInstanceId(vm.getId());
+                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                // save work context info (there are some duplications)
-                VmWorkCreateVMSnapshot workInfo = new VmWorkCreateVMSnapshot(callingUser.getId(), callingAccount.getId(), vm.getId(),
-                        VMSnapshotManagerImpl.VM_WORK_JOB_HANDLER, vmSnapshotId, quiesceVm);
-                workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                    // save work context info (there are some duplications)
+                    VmWorkCreateVMSnapshot workInfo = new VmWorkCreateVMSnapshot(callingUser.getId(), callingAccount.getId(), vm.getId(),
+                            VMSnapshotManagerImpl.VM_WORK_JOB_HANDLER, vmSnapshotId, quiesceVm);
+                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-                return new Object[] {workJob, new Long(workJob.getId())};
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
+                }
             }
         });
 
@@ -907,27 +911,31 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
             public Object[] doInTransaction(TransactionStatus status) {
                 VmWorkJobVO workJob = null;
 
-                _vmInstanceDao.lockRow(vm.getId(), true);
-                workJob = new VmWorkJobVO(context.getContextId());
+                _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    workJob = new VmWorkJobVO(context.getContextId());
 
-                workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                workJob.setCmd(VmWorkDeleteVMSnapshot.class.getName());
+                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                    workJob.setCmd(VmWorkDeleteVMSnapshot.class.getName());
 
-                workJob.setAccountId(callingAccount.getId());
-                workJob.setUserId(callingUser.getId());
-                workJob.setStep(VmWorkJobVO.Step.Starting);
-                workJob.setVmType(VirtualMachine.Type.Instance);
-                workJob.setVmInstanceId(vm.getId());
-                workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                    workJob.setAccountId(callingAccount.getId());
+                    workJob.setUserId(callingUser.getId());
+                    workJob.setStep(VmWorkJobVO.Step.Starting);
+                    workJob.setVmType(VirtualMachine.Type.Instance);
+                    workJob.setVmInstanceId(vm.getId());
+                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                // save work context info (there are some duplications)
-                VmWorkDeleteVMSnapshot workInfo = new VmWorkDeleteVMSnapshot(callingUser.getId(), callingAccount.getId(), vm.getId(),
-                        VMSnapshotManagerImpl.VM_WORK_JOB_HANDLER, vmSnapshotId);
-                workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                    // save work context info (there are some duplications)
+                    VmWorkDeleteVMSnapshot workInfo = new VmWorkDeleteVMSnapshot(callingUser.getId(), callingAccount.getId(), vm.getId(),
+                            VMSnapshotManagerImpl.VM_WORK_JOB_HANDLER, vmSnapshotId);
+                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-                return new Object[] {workJob, new Long(workJob.getId())};
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
+                }
             }
         });
 
@@ -951,27 +959,31 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
             public Object[] doInTransaction(TransactionStatus status) {
                 VmWorkJobVO workJob = null;
 
-                _vmInstanceDao.lockRow(vm.getId(), true);
-                workJob = new VmWorkJobVO(context.getContextId());
+                _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    workJob = new VmWorkJobVO(context.getContextId());
 
-                workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                workJob.setCmd(VmWorkRevertToVMSnapshot.class.getName());
+                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                    workJob.setCmd(VmWorkRevertToVMSnapshot.class.getName());
 
-                workJob.setAccountId(callingAccount.getId());
-                workJob.setUserId(callingUser.getId());
-                workJob.setStep(VmWorkJobVO.Step.Starting);
-                workJob.setVmType(VirtualMachine.Type.Instance);
-                workJob.setVmInstanceId(vm.getId());
-                workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                    workJob.setAccountId(callingAccount.getId());
+                    workJob.setUserId(callingUser.getId());
+                    workJob.setStep(VmWorkJobVO.Step.Starting);
+                    workJob.setVmType(VirtualMachine.Type.Instance);
+                    workJob.setVmInstanceId(vm.getId());
+                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                // save work context info (there are some duplications)
-                VmWorkRevertToVMSnapshot workInfo = new VmWorkRevertToVMSnapshot(callingUser.getId(), callingAccount.getId(), vm.getId(),
-                        VMSnapshotManagerImpl.VM_WORK_JOB_HANDLER, vmSnapshotId);
-                workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                    // save work context info (there are some duplications)
+                    VmWorkRevertToVMSnapshot workInfo = new VmWorkRevertToVMSnapshot(callingUser.getId(), callingAccount.getId(), vm.getId(),
+                            VMSnapshotManagerImpl.VM_WORK_JOB_HANDLER, vmSnapshotId);
+                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-                return new Object[] {workJob, new Long(workJob.getId())};
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
+                }
             }
         });
 
@@ -995,27 +1007,31 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
             public Object[] doInTransaction(TransactionStatus status) {
                 VmWorkJobVO workJob = null;
 
-                _vmInstanceDao.lockRow(vm.getId(), true);
-                workJob = new VmWorkJobVO(context.getContextId());
+                _vmInstanceDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+                try {
+                    workJob = new VmWorkJobVO(context.getContextId());
 
-                workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                workJob.setCmd(VmWorkDeleteAllVMSnapshots.class.getName());
+                    workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+                    workJob.setCmd(VmWorkDeleteAllVMSnapshots.class.getName());
 
-                workJob.setAccountId(callingAccount.getId());
-                workJob.setUserId(callingUser.getId());
-                workJob.setStep(VmWorkJobVO.Step.Starting);
-                workJob.setVmType(VirtualMachine.Type.Instance);
-                workJob.setVmInstanceId(vm.getId());
-                workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
+                    workJob.setAccountId(callingAccount.getId());
+                    workJob.setUserId(callingUser.getId());
+                    workJob.setStep(VmWorkJobVO.Step.Starting);
+                    workJob.setVmType(VirtualMachine.Type.Instance);
+                    workJob.setVmInstanceId(vm.getId());
+                    workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
 
-                // save work context info (there are some duplications)
-                VmWorkDeleteAllVMSnapshots workInfo = new VmWorkDeleteAllVMSnapshots(callingUser.getId(), callingAccount.getId(), vm.getId(),
-                        VMSnapshotManagerImpl.VM_WORK_JOB_HANDLER, type);
-                workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+                    // save work context info (there are some duplications)
+                    VmWorkDeleteAllVMSnapshots workInfo = new VmWorkDeleteAllVMSnapshots(callingUser.getId(), callingAccount.getId(), vm.getId(),
+                            VMSnapshotManagerImpl.VM_WORK_JOB_HANDLER, type);
+                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-                return new Object[] {workJob, new Long(workJob.getId())};
+                    return new Object[] {workJob, new Long(workJob.getId())};
+                } finally {
+                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
+                }
             }
         });