You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2014/11/03 20:13:04 UTC

[1/2] CLOUDSTACK-7833: VM Async work jobs log "Was unable to find lock for the key vm_instance" errors as warning

Repository: cloudstack
Updated Branches:
  refs/heads/master ffaabdc13 -> 684889f0b


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/684889f0/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 c30dc29..6590a74 100644
--- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
+++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
@@ -82,9 +82,6 @@ import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.Filter;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VMInstanceVO;
@@ -865,44 +862,28 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
 
         final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                VmWorkJobVO workJob = null;
+        VmWorkJobVO 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.getOriginJobId());
-
-                // 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));
+        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.getOriginJobId());
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        // 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));
 
-                return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVMSnapshotOutcome((VmWorkJobVO)result[0],
-                vmSnapshotId);
+        return new VmJobVMSnapshotOutcome(workJob,vmSnapshotId);
     }
 
     public Outcome<VMSnapshot> deleteVMSnapshotThroughJobQueue(final Long vmId, final Long vmSnapshotId) {
@@ -913,44 +894,28 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
 
         final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                VmWorkJobVO workJob = null;
+        VmWorkJobVO 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.getOriginJobId());
-
-                // 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));
+        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.getOriginJobId());
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        // 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));
 
-                return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVMSnapshotOutcome((VmWorkJobVO)result[0],
-                vmSnapshotId);
+        return new VmJobVMSnapshotOutcome(workJob,vmSnapshotId);
     }
 
     public Outcome<VMSnapshot> revertToVMSnapshotThroughJobQueue(final Long vmId, final Long vmSnapshotId) {
@@ -961,44 +926,28 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
 
         final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                VmWorkJobVO workJob = null;
+        VmWorkJobVO 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.getOriginJobId());
-
-                // 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));
+        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.getOriginJobId());
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        // 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));
 
-                return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVMSnapshotOutcome((VmWorkJobVO)result[0],
-                vmSnapshotId);
+        return new VmJobVMSnapshotOutcome(workJob,vmSnapshotId);
     }
 
     public Outcome<VirtualMachine> deleteAllVMSnapshotsThroughJobQueue(final Long vmId, final VMSnapshot.Type type) {
@@ -1009,44 +958,28 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
 
         final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                VmWorkJobVO workJob = null;
+        VmWorkJobVO 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.getOriginJobId());
-
-                // 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));
+        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.getOriginJobId());
 
-                _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        // 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));
 
-                return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVirtualMachineOutcome((VmWorkJobVO)result[0],
-                vmId);
+        return new VmJobVirtualMachineOutcome(workJob,vmId);
     }
 
     @ReflectionUse


[2/2] git commit: updated refs/heads/master to 684889f

Posted by mc...@apache.org.
CLOUDSTACK-7833: VM Async work jobs log "Was unable to find lock for the key vm_instance" errors as warning


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

Branch: refs/heads/master
Commit: 684889f0b5a7ae0e1e17e7d84efb1523e2f49017
Parents: ffaabdc
Author: Min Chen <mi...@citrix.com>
Authored: Thu Oct 30 18:14:15 2014 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Mon Nov 3 10:52:47 2014 -0800

----------------------------------------------------------------------
 .../com/cloud/vm/VirtualMachineManagerImpl.java | 773 ++++++++-----------
 .../jobs/impl/AsyncJobManagerImpl.java          |  67 +-
 .../com/cloud/storage/VolumeApiServiceImpl.java | 247 ++----
 .../vm/snapshot/VMSnapshotManagerImpl.java      | 195 ++---
 4 files changed, 486 insertions(+), 796 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/684889f0/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 32bf54c..2b244ef 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -183,7 +183,6 @@ import com.cloud.utils.db.DB;
 import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.GlobalLock;
 import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
 import com.cloud.utils.db.TransactionCallbackWithException;
 import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
 import com.cloud.utils.db.TransactionLegacy;
@@ -3932,55 +3931,38 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 
         final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                VmWorkJobVO workJob = null;
+        VmWorkJobVO workJob = null;
+        List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(VirtualMachine.Type.Instance,
+                vm.getId(), VmWorkStart.class.getName());
 
-                _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.getOriginJobId());
-
-                        // 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);
-                        if (planner != null) {
-                            workInfo.setDeploymentPlanner(planner.getName());
-                        }
-                        workInfo.setParams(params);
-                        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+        if (pendingWorkJobs.size() > 0) {
+            assert (pendingWorkJobs.size() == 1);
+            workJob = pendingWorkJobs.get(0);
+        } else {
+            workJob = new VmWorkJobVO(context.getContextId());
 
-                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-                    }
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkStart.class.getName());
 
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+            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.getOriginJobId());
+
+            // 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));
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmStateSyncOutcome((VmWorkJobVO)result[0],
+        return new VmStateSyncOutcome(workJob,
                 VirtualMachine.PowerState.PowerOn, vm.getId(), null);
     }
 
@@ -3991,51 +3973,37 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 
         final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
+        List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                vm.getType(), vm.getId(),
+                VmWorkStop.class.getName());
 
-                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.getOriginJobId());
-
-                        // 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());
-                    }
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert (pendingWorkJobs.size() == 1);
+            workJob = pendingWorkJobs.get(0);
+        } else {
+            workJob = new VmWorkJobVO(context.getContextId());
 
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+            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.getOriginJobId());
+
+            // 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());
+        }
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmStateSyncOutcome((VmWorkJobVO)result[0],
+        return new VmStateSyncOutcome(workJob,
                 VirtualMachine.PowerState.PowerOff, vm.getId(), null);
     }
 
@@ -4048,50 +4016,37 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 
         final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                _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.getOriginJobId());
-
-                        // 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());
-                    }
+        List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkReboot.class.getName());
 
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+        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.getOriginJobId());
+
+            // 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());
+        }
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVirtualMachineOutcome((VmWorkJobVO)result[0],
+        return new VmJobVirtualMachineOutcome(workJob,
                 vm.getId());
     }
 
@@ -4102,50 +4057,37 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 
         final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-
-                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
-                try {
-                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                            VirtualMachine.Type.Instance, vm.getId(),
-                            VmWorkMigrate.class.getName());
+        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.getOriginJobId());
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
 
-                        // 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());
-                    }
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmStateSyncOutcome((VmWorkJobVO)result[0],
+        return new VmStateSyncOutcome(workJob,
                 VirtualMachine.PowerState.PowerOn, vm.getId(), vm.getPowerHostId());
     }
 
@@ -4156,49 +4098,36 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 
         final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                _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.getOriginJobId());
-
-                        // 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()));
-                }
-            }
-        });
+        List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkMigrateAway.class.getName());
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert (pendingWorkJobs.size() == 1);
+            workJob = pendingWorkJobs.get(0);
+        } else {
+            workJob = new VmWorkJobVO(context.getContextId());
 
-        return new VmStateSyncOutcome((VmWorkJobVO)result[0],
-                VirtualMachine.PowerState.PowerOn, vm.getId(), vm.getPowerHostId());
+            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.getOriginJobId());
+
+            // 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());
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmStateSyncOutcome(workJob, VirtualMachine.PowerState.PowerOn, vm.getId(), vm.getPowerHostId());
     }
 
     public Outcome<VirtualMachine> migrateVmWithStorageThroughJobQueue(
@@ -4211,51 +4140,37 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 
         final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-
-                _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 {
+        List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkMigrateWithStorage.class.getName());
 
-                        workJob = new VmWorkJobVO(context.getContextId());
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert (pendingWorkJobs.size() == 1);
+            workJob = pendingWorkJobs.get(0);
+        } else {
 
-                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                        workJob.setCmd(VmWorkMigrate.class.getName());
+            workJob = new VmWorkJobVO(context.getContextId());
 
-                        workJob.setAccountId(account.getId());
-                        workJob.setUserId(user.getId());
-                        workJob.setVmType(VirtualMachine.Type.Instance);
-                        workJob.setVmInstanceId(vm.getId());
-                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkMigrate.class.getName());
 
-                        // 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));
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
 
-                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-                    }
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+            // 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));
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmStateSyncOutcome((VmWorkJobVO)result[0],
+        return new VmStateSyncOutcome(workJob,
                 VirtualMachine.PowerState.PowerOn, vm.getId(), destHostId);
     }
 
@@ -4268,52 +4183,37 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 
         final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-
-                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
-                try {
-                    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 {
-
-                        workJob = new VmWorkJobVO(context.getContextId());
+        List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkMigrateForScale.class.getName());
 
-                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                        workJob.setCmd(VmWorkMigrate.class.getName());
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert (pendingWorkJobs.size() == 1);
+            workJob = pendingWorkJobs.get(0);
+        } else {
 
-                        workJob.setAccountId(account.getId());
-                        workJob.setUserId(user.getId());
-                        workJob.setVmType(VirtualMachine.Type.Instance);
-                        workJob.setVmInstanceId(vm.getId());
-                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+            workJob = new VmWorkJobVO(context.getContextId());
 
-                        // 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));
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkMigrate.class.getName());
 
-                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-                    }
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
 
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+            // 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));
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVirtualMachineOutcome((VmWorkJobVO)result[0], vm.getId());
+        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
     }
 
     public Outcome<VirtualMachine> migrateVmStorageThroughJobQueue(
@@ -4325,52 +4225,37 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 
         final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-
-                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
-                try {
-                    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 {
-
-                        workJob = new VmWorkJobVO(context.getContextId());
+        List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkStorageMigration.class.getName());
 
-                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                        workJob.setCmd(VmWorkStorageMigration.class.getName());
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert (pendingWorkJobs.size() == 1);
+            workJob = pendingWorkJobs.get(0);
+        } else {
 
-                        workJob.setAccountId(account.getId());
-                        workJob.setUserId(user.getId());
-                        workJob.setVmType(VirtualMachine.Type.Instance);
-                        workJob.setVmInstanceId(vm.getId());
-                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+            workJob = new VmWorkJobVO(context.getContextId());
 
-                        // 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));
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkStorageMigration.class.getName());
 
-                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-                    }
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
 
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+            // 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));
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVirtualMachineOutcome((VmWorkJobVO)result[0], vm.getId());
+        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
     }
 
     public Outcome<VirtualMachine> addVmToNetworkThroughJobQueue(
@@ -4380,52 +4265,37 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
         final User user = context.getCallingUser();
         final Account account = context.getCallingAccount();
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-
-                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
-
-                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 {
+        List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkAddVmToNetwork.class.getName());
 
-                        workJob = new VmWorkJobVO(context.getContextId());
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert (pendingWorkJobs.size() == 1);
+            workJob = pendingWorkJobs.get(0);
+        } else {
 
-                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                        workJob.setCmd(VmWorkAddVmToNetwork.class.getName());
+            workJob = new VmWorkJobVO(context.getContextId());
 
-                        workJob.setAccountId(account.getId());
-                        workJob.setUserId(user.getId());
-                        workJob.setVmType(VirtualMachine.Type.Instance);
-                        workJob.setVmInstanceId(vm.getId());
-                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkAddVmToNetwork.class.getName());
 
-                        // 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));
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
 
-                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-                    }
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+            // 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));
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVirtualMachineOutcome((VmWorkJobVO)result[0], vm.getId());
+        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
     }
 
     public Outcome<VirtualMachine> removeNicFromVmThroughJobQueue(
@@ -4435,51 +4305,37 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
         final User user = context.getCallingUser();
         final Account account = context.getCallingAccount();
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-
-                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
-                try {
-                    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 {
+        List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkRemoveNicFromVm.class.getName());
 
-                        workJob = new VmWorkJobVO(context.getContextId());
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert (pendingWorkJobs.size() == 1);
+            workJob = pendingWorkJobs.get(0);
+        } else {
 
-                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                        workJob.setCmd(VmWorkRemoveNicFromVm.class.getName());
+            workJob = new VmWorkJobVO(context.getContextId());
 
-                        workJob.setAccountId(account.getId());
-                        workJob.setUserId(user.getId());
-                        workJob.setVmType(VirtualMachine.Type.Instance);
-                        workJob.setVmInstanceId(vm.getId());
-                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkRemoveNicFromVm.class.getName());
 
-                        // 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));
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
 
-                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-                    }
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+            // 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));
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVirtualMachineOutcome((VmWorkJobVO)result[0], vm.getId());
+        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
     }
 
     public Outcome<VirtualMachine> removeVmFromNetworkThroughJobQueue(
@@ -4489,51 +4345,38 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
         final User user = context.getCallingUser();
         final Account account = context.getCallingAccount();
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-
-                _vmDao.lockInLockTable(String.valueOf(vm.getId()), Integer.MAX_VALUE);
-                try {
-                    List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                            VirtualMachine.Type.Instance, vm.getId(),
-                            VmWorkRemoveVmFromNetwork.class.getName());
+        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.getOriginJobId());
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
 
-                        // 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());
-                    }
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVirtualMachineOutcome((VmWorkJobVO)result[0], vm.getId());
+        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
     }
 
     public Outcome<VirtualMachine> reconfigureVmThroughJobQueue(
@@ -4545,51 +4388,37 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 
         final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-
-                _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 {
+        List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkReconfigure.class.getName());
 
-                        workJob = new VmWorkJobVO(context.getContextId());
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert (pendingWorkJobs.size() == 1);
+            workJob = pendingWorkJobs.get(0);
+        } else {
 
-                        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-                        workJob.setCmd(VmWorkReconfigure.class.getName());
+            workJob = new VmWorkJobVO(context.getContextId());
 
-                        workJob.setAccountId(account.getId());
-                        workJob.setUserId(user.getId());
-                        workJob.setVmType(VirtualMachine.Type.Instance);
-                        workJob.setVmInstanceId(vm.getId());
-                        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkReconfigure.class.getName());
 
-                        // 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));
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
 
-                        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-                    }
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+            // 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));
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVirtualMachineOutcome((VmWorkJobVO)result[0], vm.getId());
+        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
     }
 
     @ReflectionUse

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/684889f0/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java
index aab1683..548182a 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java
@@ -79,6 +79,7 @@ import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.exception.ExceptionUtil;
 import com.cloud.utils.mgmt.JmxUtil;
+import com.cloud.vm.dao.VMInstanceDao;
 
 public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, ClusterManagerListener, Configurable {
     // Advanced
@@ -86,6 +87,9 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
         "Time (in minutes) for async-jobs to be kept in system", true, ConfigKey.Scope.Global);
     private static final ConfigKey<Long> JobCancelThresholdMinutes = new ConfigKey<Long>("Advanced", Long.class, "job.cancel.threshold.minutes", "60",
         "Time (in minutes) for async-jobs to be forcely cancelled if it has been in process for long", true, ConfigKey.Scope.Global);
+    private static final ConfigKey<Integer> VmJobLockTimeout = new ConfigKey<Integer>("Advanced",
+            Integer.class, "vm.job.lock.timeout", "1800",
+            "Time in seconds to wait in acquiring lock to submit a vm worker job", false);
 
     private static final Logger s_logger = Logger.getLogger(AsyncJobManagerImpl.class);
 
@@ -111,6 +115,8 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
     private MessageBus _messageBus;
     @Inject
     private AsyncJobMonitor _jobMonitor;
+    @Inject
+    private VMInstanceDao _vmInstanceDao;
 
     private volatile long _executionRunNumber = 1;
 
@@ -125,7 +131,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
 
     @Override
     public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {JobExpireMinutes, JobCancelThresholdMinutes};
+        return new ConfigKey<?>[] {JobExpireMinutes, JobCancelThresholdMinutes, VmJobLockTimeout};
     }
 
     @Override
@@ -185,18 +191,27 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
             @SuppressWarnings("rawtypes")
             final GenericDao dao = GenericDaoBase.getDao(job.getClass());
 
-            return Transaction.execute(new TransactionCallback<Long>() {
-                @Override
-                public Long doInTransaction(TransactionStatus status) {
-                    job.setInitMsid(getMsid());
-                    dao.persist(job);
+            publishOnEventBus(job, "submit");
 
-                    publishOnEventBus(job, "submit");
-                    syncAsyncJobExecution(job, syncObjType, syncObjId, 1);
+            if (!_vmInstanceDao.lockInLockTable(String.valueOf(syncObjId), VmJobLockTimeout.value())){
+                throw new CloudRuntimeException("Failed to acquire lock in submitting async job: " + job.getCmd() + " with timeout value = " + VmJobLockTimeout.value());
+            }
 
-                    return job.getId();
-                }
-            });
+            try {
+                // lock is acquired
+                return Transaction.execute(new TransactionCallback<Long>() {
+                    @Override
+                    public Long doInTransaction(TransactionStatus status) {
+                        job.setInitMsid(getMsid());
+                        dao.persist(job);
+
+                        syncAsyncJobExecution(job, syncObjType, syncObjId, 1);
+                        return job.getId();
+                    }
+                });
+            } finally {
+                _vmInstanceDao.unlockFromLockTable(String.valueOf(syncObjId));
+            }
         } catch (Exception e) {
             String errMsg = "Unable to schedule async job for command " + job.getCmd() + ", unexpected exception.";
             s_logger.warn(errMsg, e);
@@ -239,13 +254,13 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
         publishOnEventBus(job, "complete"); // publish before the instance type and ID are wiped out
 
         if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Wake up jobs related to job- " + jobId);
+            s_logger.debug("Wake up jobs related to job-" + jobId);
         }
         List<Long> wakeupList = Transaction.execute(new TransactionCallback<List<Long>>() {
             @Override
             public List<Long> doInTransaction(TransactionStatus status) {
                 if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Update db status for job- " + jobId);
+                    s_logger.debug("Update db status for job-" + jobId);
                 }
                 job.setCompleteMsid(getMsid());
                 job.setStatus(jobStatus);
@@ -262,15 +277,13 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                 _jobDao.update(jobId, job);
 
                 if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Wake up jobs joined with job- " + jobId + " and disjoin all subjobs created from job- " + jobId);
+                    s_logger.debug("Wake up jobs joined with job-" + jobId + " and disjoin all subjobs created from job- " + jobId);
                 }
                 List<Long> wakeupList = wakeupByJoinedJobCompletion(jobId);
                 _joinMapDao.disjoinAllJobs(jobId);
 
                 // purge the job sync item from queue
-                if (job.getSyncSource() != null) {
-                    _queueMgr.purgeItem(job.getSyncSource().getId());
-                }
+                _queueMgr.purgeAsyncJobQueueItemId(jobId);
 
                 return wakeupList;
             }
@@ -856,20 +869,16 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
             final SearchCriteria<AsyncJobVO> jobsSC = JobIdsSearch.create("ids", ids);
             final SearchCriteria<SyncQueueItemVO> queueItemsSC = QueueJobIdsSearch.create("contentIds", ids);
 
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    AsyncJobVO job = _jobDao.createForUpdate();
-                    job.setPendingSignals(AsyncJob.Constants.SIGNAL_MASK_WAKEUP);
-                    _jobDao.update(job, jobsSC);
+            AsyncJobVO job = _jobDao.createForUpdate();
+            job.setPendingSignals(AsyncJob.Constants.SIGNAL_MASK_WAKEUP);
+            _jobDao.update(job, jobsSC);
 
-                    SyncQueueItemVO item = _queueItemDao.createForUpdate();
-                    item.setLastProcessNumber(null);
-                    item.setLastProcessMsid(null);
-                    _queueItemDao.update(item, queueItemsSC);
-                }
-            });
+            SyncQueueItemVO item = _queueItemDao.createForUpdate();
+            item.setLastProcessNumber(null);
+            item.setLastProcessMsid(null);
+            _queueItemDao.update(item, queueItemsSC);
         }
+
         return _joinMapDao.findJobsToWake(joinedJobId);
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/684889f0/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 5f237b0..088f054 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -2401,47 +2401,31 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                VmWorkJobVO workJob = null;
+        VmWorkJobVO 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.getOriginJobId());
 
-                    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.getOriginJobId());
+        // 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());
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
-
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
-
-        return new VmJobVolumeOutcome((VmWorkJobVO)result[0],
-                volumeId);
+        return new VmJobVolumeOutcome(workJob, volumeId);
     }
 
     public Outcome<Volume> detachVolumeFromVmThroughJobQueue(final Long vmId, final Long volumeId) {
@@ -2452,44 +2436,28 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                VmWorkJobVO workJob = null;
-
-                _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());
+        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
 
-                    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.getOriginJobId());
+        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+        workJob.setCmd(VmWorkDetachVolume.class.getName());
 
-                    // 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));
+        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.getOriginJobId());
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        // 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));
 
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVolumeOutcome((VmWorkJobVO)result[0],
-                volumeId);
+        return new VmJobVolumeOutcome(workJob, volumeId);
     }
 
     public Outcome<Volume> resizeVolumeThroughJobQueue(final Long vmId, final long volumeId,
@@ -2501,45 +2469,28 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                VmWorkJobVO workJob = null;
-
-                _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());
+        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
 
-                    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.getOriginJobId());
+        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+        workJob.setCmd(VmWorkResizeVolume.class.getName());
 
-                    // 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, newMinIops, newMaxIops, newServiceOfferingId, shrinkOk);
-                    workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+        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.getOriginJobId());
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        // 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, newMinIops, newMaxIops, newServiceOfferingId, shrinkOk);
+        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
 
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobVolumeOutcome((VmWorkJobVO)result[0],
-                volumeId);
+        return new VmJobVolumeOutcome(workJob,volumeId);
     }
 
     public Outcome<Volume> migrateVolumeThroughJobQueue(final Long vmId, final long volumeId,
@@ -2551,44 +2502,28 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                VmWorkJobVO workJob = null;
+        VmWorkJobVO 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.getOriginJobId());
 
-                    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.getOriginJobId());
+        // 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());
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
-
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
-
-        return new VmJobVolumeOutcome((VmWorkJobVO)result[0],
-                volumeId);
+        return new VmJobVolumeOutcome(workJob,volumeId);
     }
 
     public Outcome<Snapshot> takeVolumeSnapshotThroughJobQueue(final Long vmId, final Long volumeId,
@@ -2600,45 +2535,29 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
 
-        Object[] result = Transaction.execute(new TransactionCallback<Object[]>() {
-            @Override
-            public Object[] doInTransaction(TransactionStatus status) {
-                VmWorkJobVO workJob = null;
-
-                _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());
+        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
 
-                    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.getOriginJobId());
+        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+        workJob.setCmd(VmWorkTakeVolumeSnapshot.class.getName());
 
-                    // 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));
+        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.getOriginJobId());
 
-                    _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        // 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));
 
-                    return new Object[] {workJob, new Long(workJob.getId())};
-                } finally {
-                    _vmInstanceDao.unlockFromLockTable(String.valueOf(vm.getId()));
-                }
-            }
-        });
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
 
-        final long jobId = (Long)result[1];
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
 
-        return new VmJobSnapshotOutcome((VmWorkJobVO)result[0],
-                snapshotId);
+        return new VmJobSnapshotOutcome(workJob,snapshotId);
     }
 
     @ReflectionUse