You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2013/10/23 21:43:37 UTC

[20/47] New Transaction API

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/server/src/com/cloud/projects/ProjectManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java
index a385739..193a49e 100755
--- a/server/src/com/cloud/projects/ProjectManagerImpl.java
+++ b/server/src/com/cloud/projects/ProjectManagerImpl.java
@@ -82,6 +82,10 @@ import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.sun.mail.smtp.SMTPMessage;
 import com.sun.mail.smtp.SMTPSSLTransport;
@@ -175,7 +179,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", create=true)
     @DB
-    public Project createProject(String name, String displayText, String accountName, Long domainId) throws ResourceAllocationException{
+    public Project createProject(final String name, final String displayText, String accountName, final Long domainId) throws ResourceAllocationException{
         Account caller = CallContext.current().getCallingAccount();
         Account owner = caller;
 
@@ -201,30 +205,32 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
         //do resource limit check
         _resourceLimitMgr.checkResourceLimit(owner, ResourceType.project);
 
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
+        final Account ownerFinal = owner;
+        return Transaction.execute(new TransactionCallback<Project>() {
+            @Override
+            public Project doInTransaction(TransactionStatus status) {
 
-        //Create an account associated with the project
-        StringBuilder acctNm = new StringBuilder("PrjAcct-");
-        acctNm.append(name).append("-").append(owner.getDomainId());
-
-        Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString());
-
-        Project project = _projectDao.persist(new ProjectVO(name, displayText, owner.getDomainId(), projectAccount.getId()));
-
-        //assign owner to the project
-        assignAccountToProject(project, owner.getId(), ProjectAccount.Role.Admin);
-
-        if (project != null) {
-            CallContext.current().setEventDetails("Project id=" + project.getId());
-        }
-
-        //Increment resource count
-        _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.project);
-
-        txn.commit();
+                //Create an account associated with the project
+                StringBuilder acctNm = new StringBuilder("PrjAcct-");
+                acctNm.append(name).append("-").append(ownerFinal.getDomainId());
+        
+                Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString());
+        
+                Project project = _projectDao.persist(new ProjectVO(name, displayText, ownerFinal.getDomainId(), projectAccount.getId()));
+        
+                //assign owner to the project
+                assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin);
+        
+                if (project != null) {
+                    CallContext.current().setEventDetails("Project id=" + project.getId());
+                }
+        
+                //Increment resource count
+                _resourceLimitMgr.incrementResourceCount(ownerFinal.getId(), ResourceType.project);
 
-        return project;
+                return project;
+            }
+        });
     }
 
 
@@ -268,20 +274,24 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
 
     @DB
     @Override
-    public boolean deleteProject(Account caller, long callerUserId, ProjectVO project) {
+    public boolean deleteProject(Account caller, long callerUserId, final ProjectVO project) {
         //mark project as inactive first, so you can't add resources to it
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        s_logger.debug("Marking project id=" + project.getId() + " with state " + State.Disabled + " as a part of project delete...");
-        project.setState(State.Disabled);
-        boolean updateResult = _projectDao.update(project.getId(), project);
-        //owner can be already removed at this point, so adding the conditional check
-        Account projectOwner = getProjectOwner(project.getId());
-        if (projectOwner != null) {
-            _resourceLimitMgr.decrementResourceCount(projectOwner.getId(), ResourceType.project);
-        } 
+        boolean updateResult = Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(TransactionStatus status) {
+                s_logger.debug("Marking project id=" + project.getId() + " with state " + State.Disabled + " as a part of project delete...");
+                project.setState(State.Disabled);
+                boolean updateResult = _projectDao.update(project.getId(), project);
+                //owner can be already removed at this point, so adding the conditional check
+                Account projectOwner = getProjectOwner(project.getId());
+                if (projectOwner != null) {
+                    _resourceLimitMgr.decrementResourceCount(projectOwner.getId(), ResourceType.project);
+                }
+
+                return updateResult;
+            }
+        });
 
-        txn.commit();
 
         if (updateResult) {
             //pass system caller when clenaup projects account
@@ -298,7 +308,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
     }
 
     @DB
-    private boolean cleanupProject(Project project, AccountVO caller, Long callerUserId) {
+    private boolean cleanupProject(final Project project, AccountVO caller, Long callerUserId) {
         boolean result=true; 
         //Delete project's account
         AccountVO account = _accountDao.findById(project.getProjectAccountId());
@@ -308,20 +318,22 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
 
         if (result) {
             //Unassign all users from the project
-
-            Transaction txn = Transaction.currentTxn();
-            txn.start();
-
-            s_logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup...");
-            List<? extends ProjectAccount> projectAccounts = _projectAccountDao.listByProjectId(project.getId());
-            for (ProjectAccount projectAccount : projectAccounts) {
-                result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId());
-            }
-
-            s_logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup...");
-            _projectInvitationDao.cleanupInvitations(project.getId());
-
-            txn.commit();
+            result = Transaction.execute(new TransactionCallback<Boolean>() {
+                @Override
+                public Boolean doInTransaction(TransactionStatus status) {
+                    boolean result = true;
+                    s_logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup...");
+                    List<? extends ProjectAccount> projectAccounts = _projectAccountDao.listByProjectId(project.getId());
+                    for (ProjectAccount projectAccount : projectAccounts) {
+                        result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId());
+                    }
+        
+                    s_logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup...");
+                    _projectInvitationDao.cleanupInvitations(project.getId());
+                    
+                    return result;
+                }
+            });
             if (result) {
                 s_logger.debug("Accounts are unassign successfully from project " + project + " as a part of project cleanup...");
             }
@@ -366,26 +378,28 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
     }
 
     @Override @DB
-    public boolean deleteAccountFromProject(long projectId, long accountId) {
-        boolean success = true;
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
+    public boolean deleteAccountFromProject(final long projectId, final long accountId) {
+        return Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(TransactionStatus status) {
+                boolean success = true;
+
+                //remove account
+                ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
+                success = _projectAccountDao.remove(projectAccount.getId());
+
+                //remove all invitations for account
+                if (success) {
+                    s_logger.debug("Removed account " + accountId + " from project " + projectId + " , cleaning up old invitations for account/project...");
+                    ProjectInvitation invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId);
+                    if (invite != null) {
+                        success = success && _projectInvitationDao.remove(invite.getId());
+                    }
+                }
 
-        //remove account
-        ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
-        success = _projectAccountDao.remove(projectAccount.getId());
-
-        //remove all invitations for account
-        if (success) {
-            s_logger.debug("Removed account " + accountId + " from project " + projectId + " , cleaning up old invitations for account/project...");
-            ProjectInvitation invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId);
-            if (invite != null) {
-                success = success && _projectInvitationDao.remove(invite.getId());
+                return success;
             }
-        }
-
-        txn.commit();
-        return success;
+        });
     }
 
     @Override
@@ -442,11 +456,11 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
 
     @Override @DB
     @ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async=true)
-    public Project updateProject(long projectId, String displayText, String newOwnerName) throws ResourceAllocationException{
+    public Project updateProject(final long projectId, final String displayText, final String newOwnerName) throws ResourceAllocationException{
         Account caller = CallContext.current().getCallingAccount();
 
         //check that the project exists
-        ProjectVO project = getProject(projectId);
+        final ProjectVO project = getProject(projectId);
 
         if (project == null) {
             throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
@@ -455,47 +469,51 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
         //verify permissions
         _accountMgr.checkAccess(caller,AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
 
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        if (displayText != null) {
-            project.setDisplayText(displayText);
-            _projectDao.update(projectId, project);
-        }
-
-        if (newOwnerName != null) {
-            //check that the new owner exists
-            Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
-            if (futureOwnerAccount == null) {
-                throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
-            }
-            Account currentOwnerAccount = getProjectOwner(projectId);
-            if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) {
-                ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId());
-                if (futureOwner == null) {
-                    throw new InvalidParameterValueException("Account " + newOwnerName + " doesn't belong to the project. Add it to the project first and then change the project's ownership");
+        Transaction.executeWithException(new TransactionCallbackWithException<Object>() {
+            @Override
+            public Object doInTransaction(TransactionStatus status) throws ResourceAllocationException {
+                if (displayText != null) {
+                    project.setDisplayText(displayText);
+                    _projectDao.update(projectId, project);
                 }
-
-                //do resource limit check
-                _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project);
-
-                //unset the role for the old owner
-                ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
-                currentOwner.setAccountRole(Role.Regular);
-                _projectAccountDao.update(currentOwner.getId(), currentOwner);
-                _resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
-
-                //set new owner
-                futureOwner.setAccountRole(Role.Admin);
-                _projectAccountDao.update(futureOwner.getId(), futureOwner);
-                _resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
-
-
-            } else {
-                s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId);
+        
+                if (newOwnerName != null) {
+                    //check that the new owner exists
+                    Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
+                    if (futureOwnerAccount == null) {
+                        throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
+                    }
+                    Account currentOwnerAccount = getProjectOwner(projectId);
+                    if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) {
+                        ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId());
+                        if (futureOwner == null) {
+                            throw new InvalidParameterValueException("Account " + newOwnerName + " doesn't belong to the project. Add it to the project first and then change the project's ownership");
+                        }
+        
+                        //do resource limit check
+                        _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project);
+        
+                        //unset the role for the old owner
+                        ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
+                        currentOwner.setAccountRole(Role.Regular);
+                        _projectAccountDao.update(currentOwner.getId(), currentOwner);
+                        _resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
+        
+                        //set new owner
+                        futureOwner.setAccountRole(Role.Admin);
+                        _projectAccountDao.update(futureOwner.getId(), futureOwner);
+                        _resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
+        
+        
+                    } else {
+                        s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId);
+                    }
+               }
+                
+                return null;
             }
-        }
+        }, ResourceAllocationException.class);
 
-        txn.commit();
 
         return _projectDao.findById(projectId);
 
@@ -649,37 +667,40 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
     }
 
     @DB
-    public boolean activeInviteExists(Project project, Long accountId, String email) {
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        //verify if the invitation was already generated
-        ProjectInvitationVO invite = null;
-        if (accountId != null) {
-            invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId());
-        } else if (email != null) {
-            invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId());
-        }
-
-        if (invite != null) {
-            if (invite.getState() == ProjectInvitation.State.Completed || 
-                    (invite.getState() == ProjectInvitation.State.Pending && _projectInvitationDao.isActive(invite.getId(), _invitationTimeOut))) {
-                return true;
-            } else {
-                if (invite.getState() == ProjectInvitation.State.Pending) {
-                    expireInvitation(invite);
-                }
-                //remove the expired/declined invitation
+    public boolean activeInviteExists(final Project project, final Long accountId, final String email) {
+        return Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(TransactionStatus status) {
+                //verify if the invitation was already generated
+                ProjectInvitationVO invite = null;
                 if (accountId != null) {
-                    s_logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project);
+                    invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId());
                 } else if (email != null) {
-                    s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project);
+                    invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId());
+                }
+
+                if (invite != null) {
+                    if (invite.getState() == ProjectInvitation.State.Completed || 
+                            (invite.getState() == ProjectInvitation.State.Pending && _projectInvitationDao.isActive(invite.getId(), _invitationTimeOut))) {
+                        return true;
+                    } else {
+                        if (invite.getState() == ProjectInvitation.State.Pending) {
+                            expireInvitation(invite);
+                        }
+                        //remove the expired/declined invitation
+                        if (accountId != null) {
+                            s_logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project);
+                        } else if (email != null) {
+                            s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project);
+                        }
+
+                        _projectInvitationDao.expunge(invite.getId());
+                    }
                 }
 
-                _projectInvitationDao.expunge(invite.getId());
+                return false;
             }
-        }
-        txn.commit();
-        return false;
+        });
     }
 
     public ProjectInvitation generateTokenBasedInvitation(Project project, String email, String token) {
@@ -710,7 +731,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
 
     @Override @DB
     @ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_UPDATE, eventDescription = "updating project invitation", async=true)
-    public boolean updateInvitation(long projectId, String accountName, String token, boolean accept) {
+    public boolean updateInvitation(final long projectId, String accountName, String token, final boolean accept) {
         Account caller = CallContext.current().getCallingAccount();
         Long accountId = null;
         boolean result = true;
@@ -721,7 +742,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
         }
 
         //check that the project exists
-        Project project = getProject(projectId);
+        final Project project = getProject(projectId);
 
         if (project == null) {
             throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
@@ -755,29 +776,37 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
                 expireInvitation(invite);
                 throw new InvalidParameterValueException("Invitation is expired for account id=" + accountName + " to the project id=" + projectId);
             } else {
-                Transaction txn = Transaction.currentTxn();
-                txn.start();
-
-                ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined;
-
-                //update invitation
-                s_logger.debug("Marking invitation " + invite + " with state " + newState);
-                invite.setState(newState);
-                result = _projectInvitationDao.update(invite.getId(), invite);
-
-                if (result && accept) {
-                    //check if account already exists for the project (was added before invitation got accepted)
-                    ProjectAccount projectAccount =  _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
-                    if (projectAccount != null) {
-                        s_logger.debug("Account " + accountName + " already added to the project id=" + projectId);
-                    } else {
-                        assignAccountToProject(project, accountId, ProjectAccount.Role.Regular); 
+                
+                final ProjectInvitationVO inviteFinal = invite;
+                final Long accountIdFinal = accountId;
+                final String accountNameFinal = accountName;
+                result = Transaction.execute(new TransactionCallback<Boolean>() {
+                    @Override
+                    public Boolean doInTransaction(TransactionStatus status) {
+                        boolean result = true;
+                        
+                        ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined;
+        
+                        //update invitation
+                        s_logger.debug("Marking invitation " + inviteFinal + " with state " + newState);
+                        inviteFinal.setState(newState);
+                        result = _projectInvitationDao.update(inviteFinal.getId(), inviteFinal);
+        
+                        if (result && accept) {
+                            //check if account already exists for the project (was added before invitation got accepted)
+                            ProjectAccount projectAccount =  _projectAccountDao.findByProjectIdAccountId(projectId, accountIdFinal);
+                            if (projectAccount != null) {
+                                s_logger.debug("Account " + accountNameFinal + " already added to the project id=" + projectId);
+                            } else {
+                                assignAccountToProject(project, accountIdFinal, ProjectAccount.Role.Regular); 
+                            }
+                        } else {
+                            s_logger.warn("Failed to update project invitation " + inviteFinal + " with state " + newState);
+                        }
+                        
+                        return result;
                     }
-                } else {
-                    s_logger.warn("Failed to update project invitation " + invite + " with state " + newState);
-                }
-
-                txn.commit();
+                });
             }
         } else {
             throw new InvalidParameterValueException("Unable to find invitation for account name=" + accountName + " to the project id=" + projectId);
@@ -794,11 +823,11 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACTIVATE, eventDescription = "activating project")
     @DB
-    public Project activateProject(long projectId) {
+    public Project activateProject(final long projectId) {
         Account caller = CallContext.current().getCallingAccount();
 
         //check that the project exists
-        ProjectVO project = getProject(projectId);
+        final ProjectVO project = getProject(projectId);
 
         if (project == null) {
             InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
@@ -821,15 +850,15 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
             throw new InvalidParameterValueException("Can't activate the project in " + currentState + " state");
         }
 
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-
-        project.setState(Project.State.Active);
-        _projectDao.update(projectId, project);
-
-        _accountMgr.enableAccount(project.getProjectAccountId());
-
-        txn.commit();
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                project.setState(Project.State.Active);
+                _projectDao.update(projectId, project);
+        
+                _accountMgr.enableAccount(project.getProjectAccountId());
+            }
+        });
 
         return _projectDao.findById(projectId);
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java
index 7a9343c..2a245f1 100755
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@ -143,6 +143,9 @@ import com.cloud.utils.db.GlobalLock;
 import com.cloud.utils.db.QueryBuilder;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.db.SearchCriteria.Func;
 import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.db.Transaction;
@@ -783,10 +786,10 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
     }
 
     @DB
-    protected boolean doDeleteHost(long hostId, boolean isForced, boolean isForceDeleteStorage) {
+    protected boolean doDeleteHost(final long hostId, boolean isForced, final boolean isForceDeleteStorage) {
         User caller = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
         // Verify that host exists
-        HostVO host = _hostDao.findById(hostId);
+        final HostVO host = _hostDao.findById(hostId);
         if (host == null) {
             throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist");
         }
@@ -799,7 +802,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
         // Get storage pool host mappings here because they can be removed as a
         // part of handleDisconnect later
         // TODO: find out the bad boy, what's a buggy logic!
-        List<StoragePoolHostVO> pools = _storagePoolHostDao.listByHostIdIncludingRemoved(hostId);
+        final List<StoragePoolHostVO> pools = _storagePoolHostDao.listByHostIdIncludingRemoved(hostId);
 
         ResourceStateAdapter.DeleteHostAnswer answer = (ResourceStateAdapter.DeleteHostAnswer)dispatchToStateAdapters(ResourceStateAdapter.Event.DELETE_HOST, false, host,
             new Boolean(isForced), new Boolean(isForceDeleteStorage));
@@ -817,74 +820,77 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
             return true;
         }
 
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-
-        _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null);
-        _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove);
-
-        // delete host details
-        _hostDetailsDao.deleteDetails(hostId);
-
-        host.setGuid(null);
-        Long clusterId = host.getClusterId();
-        host.setClusterId(null);
-        _hostDao.update(host.getId(), host);
-
-        _hostDao.remove(hostId);
-        if (clusterId != null) {
-            List<HostVO> hosts = listAllHostsInCluster(clusterId);
-            if (hosts.size() == 0) {
-                ClusterVO cluster = _clusterDao.findById(clusterId);
-                cluster.setGuid(null);
-                _clusterDao.update(clusterId, cluster);
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+
+                _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null);
+                _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove);
+        
+                // delete host details
+                _hostDetailsDao.deleteDetails(hostId);
+        
+                host.setGuid(null);
+                Long clusterId = host.getClusterId();
+                host.setClusterId(null);
+                _hostDao.update(host.getId(), host);
+        
+                _hostDao.remove(hostId);
+                if (clusterId != null) {
+                    List<HostVO> hosts = listAllHostsInCluster(clusterId);
+                    if (hosts.size() == 0) {
+                        ClusterVO cluster = _clusterDao.findById(clusterId);
+                        cluster.setGuid(null);
+                        _clusterDao.update(clusterId, cluster);
+                    }
+                }
+        
+                try {
+                    resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId);
+                } catch (NoTransitionException e) {
+                    s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
+                }
+        
+                // Delete the associated entries in host ref table
+                _storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
+        
+                // Make sure any VMs that were marked as being on this host are cleaned up
+                List<VMInstanceVO> vms = _vmDao.listByHostId(hostId);
+                for (VMInstanceVO vm : vms) {
+                    // this is how VirtualMachineManagerImpl does it when it syncs VM states
+                    vm.setState(State.Stopped);
+                    vm.setHostId(null);
+                    _vmDao.persist(vm);
+                }
+        
+                // For pool ids you got, delete local storage host entries in pool table
+                // where
+                for (StoragePoolHostVO pool : pools) {
+                    Long poolId = pool.getPoolId();
+                    StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
+                    if (storagePool.isLocal() && isForceDeleteStorage) {
+                        storagePool.setUuid(null);
+                        storagePool.setClusterId(null);
+                        _storagePoolDao.update(poolId, storagePool);
+                        _storagePoolDao.remove(poolId);
+                        s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId);
+                    }
+                }
+        
+                // delete the op_host_capacity entry
+                Object[] capacityTypes = {Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY};
+                SearchCriteria<CapacityVO> hostCapacitySC = _capacityDao.createSearchCriteria();
+                hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
+                hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes);
+                _capacityDao.remove(hostCapacitySC);
+                // remove from dedicated resources
+                DedicatedResourceVO dr = _dedicatedDao.findByHostId(hostId);
+                if (dr != null) {
+                    _dedicatedDao.remove(dr.getId());
+                }
             }
-        }
-
-        try {
-            resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId);
-        } catch (NoTransitionException e) {
-            s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
-        }
-
-        // Delete the associated entries in host ref table
-        _storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
+        });
 
-        // Make sure any VMs that were marked as being on this host are cleaned up
-        List<VMInstanceVO> vms = _vmDao.listByHostId(hostId);
-        for (VMInstanceVO vm : vms) {
-            // this is how VirtualMachineManagerImpl does it when it syncs VM states
-            vm.setState(State.Stopped);
-            vm.setHostId(null);
-            _vmDao.persist(vm);
-        }
-
-        // For pool ids you got, delete local storage host entries in pool table
-        // where
-        for (StoragePoolHostVO pool : pools) {
-            Long poolId = pool.getPoolId();
-            StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
-            if (storagePool.isLocal() && isForceDeleteStorage) {
-                storagePool.setUuid(null);
-                storagePool.setClusterId(null);
-                _storagePoolDao.update(poolId, storagePool);
-                _storagePoolDao.remove(poolId);
-                s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId);
-            }
-        }
-
-        // delete the op_host_capacity entry
-        Object[] capacityTypes = {Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY};
-        SearchCriteria<CapacityVO> hostCapacitySC = _capacityDao.createSearchCriteria();
-        hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
-        hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes);
-        _capacityDao.remove(hostCapacitySC);
-        // remove from dedicated resources
-        DedicatedResourceVO dr = _dedicatedDao.findByHostId(hostId);
-        if (dr != null) {
-            _dedicatedDao.remove(dr.getId());
-        }
-        txn.commit();
         return true;
     }
 
@@ -904,63 +910,61 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
 
     @Override
     @DB
-    public boolean deleteCluster(DeleteClusterCmd cmd) {
-        Transaction txn = Transaction.currentTxn();
+    public boolean deleteCluster(final DeleteClusterCmd cmd) {
         try {
-            txn.start();
-            ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true);
-            if (cluster == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Cluster: " + cmd.getId() + " does not even exist.  Delete call is ignored.");
-                }
-                txn.rollback();
-                throw new CloudRuntimeException("Cluster: " + cmd.getId() + " does not exist");
-            }
-
-            Hypervisor.HypervisorType hypervisorType = cluster.getHypervisorType();
-
-            List<HostVO> hosts = listAllHostsInCluster(cmd.getId());
-            if (hosts.size() > 0) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove");
-                }
-                txn.rollback();
-                throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts");
-            }
-
-            // don't allow to remove the cluster if it has non-removed storage
-            // pools
-            List<StoragePoolVO> storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId());
-            if (storagePools.size() > 0) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove");
-                }
-                txn.rollback();
-                throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools");
-            }
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true);
+                    if (cluster == null) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Cluster: " + cmd.getId() + " does not even exist.  Delete call is ignored.");
+                        }
+                        throw new CloudRuntimeException("Cluster: " + cmd.getId() + " does not exist");
+                    }
+        
+                    Hypervisor.HypervisorType hypervisorType = cluster.getHypervisorType();
+        
+                    List<HostVO> hosts = listAllHostsInCluster(cmd.getId());
+                    if (hosts.size() > 0) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove");
+                        }
+                        throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts");
+                    }
+        
+                    // don't allow to remove the cluster if it has non-removed storage
+                    // pools
+                    List<StoragePoolVO> storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId());
+                    if (storagePools.size() > 0) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove");
+                        }
+                        throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools");
+                    }
+        
+                    if (_clusterDao.remove(cmd.getId())) {
+                        _capacityDao.removeBy(null, null, null, cluster.getId(), null);
+                        // If this cluster is of type vmware, and if the nexus vswitch
+                        // global parameter setting is turned
+                        // on, remove the row in cluster_vsm_map for this cluster id.
+                        if (hypervisorType == HypervisorType.VMware && Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) {
+                            _clusterVSMMapDao.removeByClusterId(cmd.getId());
+                        }
+                        // remove from dedicated resources
+                        DedicatedResourceVO dr = _dedicatedDao.findByClusterId(cluster.getId());
+                        if (dr != null) {
+                            _dedicatedDao.remove(dr.getId());
+                        }
+                    }
 
-            if (_clusterDao.remove(cmd.getId())) {
-                _capacityDao.removeBy(null, null, null, cluster.getId(), null);
-                // If this cluster is of type vmware, and if the nexus vswitch
-                // global parameter setting is turned
-                // on, remove the row in cluster_vsm_map for this cluster id.
-                if (hypervisorType == HypervisorType.VMware && Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) {
-                    _clusterVSMMapDao.removeByClusterId(cmd.getId());
-                }
-                // remove from dedicated resources
-                DedicatedResourceVO dr = _dedicatedDao.findByClusterId(cluster.getId());
-                if (dr != null) {
-                    _dedicatedDao.remove(dr.getId());
                 }
-            }
-
-            txn.commit();
+            });
             return true;
         } catch (CloudRuntimeException e) {
             throw e;
         } catch (Throwable t) {
             s_logger.error("Unable to delete cluster: " + cmd.getId(), t);
-            txn.rollback();
             return false;
         }
     }
@@ -1034,26 +1038,15 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
         }
 
         if (doUpdate) {
-            Transaction txn = Transaction.currentTxn();
-            try {
-                txn.start();
-                _clusterDao.update(cluster.getId(), cluster);
-                txn.commit();
-            } catch (Exception e) {
-                s_logger.error("Unable to update cluster due to " + e.getMessage(), e);
-                throw new CloudRuntimeException("Failed to update cluster. Please contact Cloud Support.");
-            }
+            _clusterDao.update(cluster.getId(), cluster);
         }
 
         if (newManagedState != null && !newManagedState.equals(oldManagedState)) {
-            Transaction txn = Transaction.currentTxn();
             if (newManagedState.equals(Managed.ManagedState.Unmanaged)) {
                 boolean success = false;
                 try {
-                    txn.start();
                     cluster.setManagedState(Managed.ManagedState.PrepareUnmanaged);
                     _clusterDao.update(cluster.getId(), cluster);
-                    txn.commit();
                     List<HostVO> hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId());
                     for (HostVO host : hosts) {
                         if (host.getType().equals(Host.Type.Routing) && !host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected) &&
@@ -1092,16 +1085,12 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
                         throw new CloudRuntimeException("PrepareUnmanaged Failed due to some hosts are still in UP status after 5 Minutes, please try later ");
                     }
                 } finally {
-                    txn.start();
                     cluster.setManagedState(success ? Managed.ManagedState.Unmanaged : Managed.ManagedState.PrepareUnmanagedError);
                     _clusterDao.update(cluster.getId(), cluster);
-                    txn.commit();
                 }
             } else if (newManagedState.equals(Managed.ManagedState.Managed)) {
-                txn.start();
                 cluster.setManagedState(Managed.ManagedState.Managed);
                 _clusterDao.update(cluster.getId(), cluster);
-                txn.commit();
             }
 
         }
@@ -2459,35 +2448,37 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
     @Override
     @DB
     @ActionEvent(eventType = EventTypes.EVENT_HOST_RESERVATION_RELEASE, eventDescription = "releasing host reservation", async = true)
-    public boolean releaseHostReservation(Long hostId) {
-        Transaction txn = Transaction.currentTxn();
+    public boolean releaseHostReservation(final Long hostId) {
         try {
-            txn.start();
-            PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
-            if (reservationEntry != null) {
-                long id = reservationEntry.getId();
-                PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true);
-                if (hostReservation == null) {
+            return Transaction.execute(new TransactionCallback<Boolean>() {
+                @Override
+                public Boolean doInTransaction(TransactionStatus status) {
+                    PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
+                    if (reservationEntry != null) {
+                        long id = reservationEntry.getId();
+                        PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true);
+                        if (hostReservation == null) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Host reservation for host: " + hostId + " does not even exist.  Release reservartion call is ignored.");
+                            }
+                            return false;
+                        }
+                        hostReservation.setResourceUsage(null);
+                        _plannerHostReserveDao.persist(hostReservation);
+                        return true;
+                    }
+
                     if (s_logger.isDebugEnabled()) {
                         s_logger.debug("Host reservation for host: " + hostId + " does not even exist.  Release reservartion call is ignored.");
                     }
-                    txn.rollback();
+
                     return false;
                 }
-                hostReservation.setResourceUsage(null);
-                _plannerHostReserveDao.persist(hostReservation);
-                txn.commit();
-                return true;
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Host reservation for host: " + hostId + " does not even exist.  Release reservartion call is ignored.");
-            }
-            return false;
+            });
         } catch (CloudRuntimeException e) {
             throw e;
         } catch (Throwable t) {
             s_logger.error("Unable to release host reservation for host: " + hostId, t);
-            txn.rollback();
             return false;
         }
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
index 1f8713a..bfe32ec 100755
--- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
+++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
@@ -90,6 +90,10 @@ import com.cloud.utils.db.GenericSearchBuilder;
 import com.cloud.utils.db.JoinBuilder;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.db.SearchCriteria.Func;
 import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.db.Transaction;
@@ -361,8 +365,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
 
     @Override
     @DB
-    public void checkResourceLimit(Account account, ResourceType type, long... count) throws ResourceAllocationException {
-        long numResources = ((count.length == 0) ? 1 : count[0]);
+    public void checkResourceLimit(final Account account, final ResourceType type, long... count) throws ResourceAllocationException {
+        final long numResources = ((count.length == 0) ? 1 : count[0]);
         Project project = null;
 
         // Don't place any limits on system or root admin accounts
@@ -374,53 +378,55 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
             project = _projectDao.findByProjectAccountId(account.getId());
         }
 
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        try {
-            // Lock all rows first so nobody else can read it
-            Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(account.getId(), ResourceOwnerType.Account, type);
-            SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
-            sc.setParameters("id", rowIdsToLock.toArray());
-            _resourceCountDao.lockRows(sc, null, true);
-
-            // Check account limits
-            long accountLimit = findCorrectResourceLimitForAccount(account, type);
-            long potentialCount = _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type) + numResources;
-            if (accountLimit != Resource.RESOURCE_UNLIMITED && potentialCount > accountLimit) {
-                String message = "Maximum number of resources of type '" + type + "' for account name=" + account.getAccountName()
-                        + " in domain id=" + account.getDomainId() + " has been exceeded.";
-                if (project != null) {
-                    message = "Maximum number of resources of type '" + type + "' for project name=" + project.getName()
+        final Project projectFinal = project;
+        Transaction.executeWithException(new TransactionCallbackWithException<Object>() {
+            @Override
+            public Object doInTransaction(TransactionStatus status) throws ResourceAllocationException {
+                // Lock all rows first so nobody else can read it
+                Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(account.getId(), ResourceOwnerType.Account, type);
+                SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
+                sc.setParameters("id", rowIdsToLock.toArray());
+                _resourceCountDao.lockRows(sc, null, true);
+    
+                // Check account limits
+                long accountLimit = findCorrectResourceLimitForAccount(account, type);
+                long potentialCount = _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type) + numResources;
+                if (accountLimit != Resource.RESOURCE_UNLIMITED && potentialCount > accountLimit) {
+                    String message = "Maximum number of resources of type '" + type + "' for account name=" + account.getAccountName()
                             + " in domain id=" + account.getDomainId() + " has been exceeded.";
+                    if (projectFinal != null) {
+                        message = "Maximum number of resources of type '" + type + "' for project name=" + projectFinal.getName()
+                                + " in domain id=" + account.getDomainId() + " has been exceeded.";
+                    }
+                    throw new ResourceAllocationException(message, type);
                 }
-                throw new ResourceAllocationException(message, type);
-            }
-
-            // check all domains in the account's domain hierarchy
-            Long domainId = null;
-            if (project != null) {
-                domainId = project.getDomainId();
-            } else {
-                domainId = account.getDomainId();
-            }
-
-            while (domainId != null) {
-                DomainVO domain = _domainDao.findById(domainId);
-                // no limit check if it is ROOT domain
-                if (domainId != Domain.ROOT_DOMAIN) {
-                    ResourceLimitVO domainLimit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type);
-                    if (domainLimit != null && domainLimit.getMax().longValue() != Resource.RESOURCE_UNLIMITED) {
-                        long domainCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type);
-                        if ((domainCount + numResources) > domainLimit.getMax().longValue()) {
-                            throw new ResourceAllocationException("Maximum number of resources of type '" + type + "' for domain id=" + domainId + " has been exceeded.", type);
+    
+                // check all domains in the account's domain hierarchy
+                Long domainId = null;
+                if (projectFinal != null) {
+                    domainId = projectFinal.getDomainId();
+                } else {
+                    domainId = account.getDomainId();
+                }
+    
+                while (domainId != null) {
+                    DomainVO domain = _domainDao.findById(domainId);
+                    // no limit check if it is ROOT domain
+                    if (domainId != Domain.ROOT_DOMAIN) {
+                        ResourceLimitVO domainLimit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type);
+                        if (domainLimit != null && domainLimit.getMax().longValue() != Resource.RESOURCE_UNLIMITED) {
+                            long domainCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type);
+                            if ((domainCount + numResources) > domainLimit.getMax().longValue()) {
+                                throw new ResourceAllocationException("Maximum number of resources of type '" + type + "' for domain id=" + domainId + " has been exceeded.", type);
+                            }
                         }
                     }
+                    domainId = domain.getParent();
                 }
-                domainId = domain.getParent();
+                
+                return null;
             }
-        } finally {
-            txn.commit();
-        }
+        }, ResourceAllocationException.class);
     }
 
     @Override
@@ -716,143 +722,143 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
     }
 
     @DB
-    protected boolean updateResourceCountForAccount(long accountId, ResourceType type, boolean increment, long delta) {
-        boolean result = true;
+    protected boolean updateResourceCountForAccount(final long accountId, final ResourceType type, final boolean increment, final long delta) {
         try {
-            Transaction txn = Transaction.currentTxn();
-            txn.start();
-
-            Set<Long> rowsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type);
-
-            // Lock rows first
-            SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
-            sc.setParameters("id", rowsToLock.toArray());
-            List<ResourceCountVO> rowsToUpdate = _resourceCountDao.lockRows(sc, null, true);
-
-            for (ResourceCountVO rowToUpdate : rowsToUpdate) {
-                if (!_resourceCountDao.updateById(rowToUpdate.getId(), increment, delta)) {
-                    s_logger.trace("Unable to update resource count for the row " + rowToUpdate);
-                    result = false;
+            return Transaction.execute(new TransactionCallback<Boolean>() {
+                @Override
+                public Boolean doInTransaction(TransactionStatus status) {
+                    boolean result = true;
+                    Set<Long> rowsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type);
+        
+                    // Lock rows first
+                    SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
+                    sc.setParameters("id", rowsToLock.toArray());
+                    List<ResourceCountVO> rowsToUpdate = _resourceCountDao.lockRows(sc, null, true);
+        
+                    for (ResourceCountVO rowToUpdate : rowsToUpdate) {
+                        if (!_resourceCountDao.updateById(rowToUpdate.getId(), increment, delta)) {
+                            s_logger.trace("Unable to update resource count for the row " + rowToUpdate);
+                            result = false;
+                        }
+                    }
+                    
+                    return result;
                 }
-            }
-
-            txn.commit();
+            });
         } catch (Exception ex) {
             s_logger.error("Failed to update resource count for account id=" + accountId);
-            result = false;
+            return false;
         }
-        return result;
     }
 
     @DB
-    protected long recalculateDomainResourceCount(long domainId, ResourceType type) {
-        long newCount = 0;
-
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-
-        try {
-            // Lock all rows first so nobody else can read it
-            Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(domainId, ResourceOwnerType.Domain, type);
-            SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
-            sc.setParameters("id", rowIdsToLock.toArray());
-            _resourceCountDao.lockRows(sc, null, true);
-
-            ResourceCountVO domainRC = _resourceCountDao.findByOwnerAndType(domainId, ResourceOwnerType.Domain, type);
-            long oldCount = domainRC.getCount();
-
-            List<DomainVO> domainChildren = _domainDao.findImmediateChildrenForParent(domainId);
-            // for each child domain update the resource count
-            if (type.supportsOwner(ResourceOwnerType.Domain)) {
-
-                // calculate project count here
-                if (type == ResourceType.project) {
-                    newCount = newCount + _projectDao.countProjectsForDomain(domainId);
+    protected long recalculateDomainResourceCount(final long domainId, final ResourceType type) {
+        return Transaction.execute(new TransactionCallback<Long>() {
+            @Override
+            public Long doInTransaction(TransactionStatus status) {
+                long newCount = 0;
+
+                // Lock all rows first so nobody else can read it
+                Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(domainId, ResourceOwnerType.Domain, type);
+                SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
+                sc.setParameters("id", rowIdsToLock.toArray());
+                _resourceCountDao.lockRows(sc, null, true);
+    
+                ResourceCountVO domainRC = _resourceCountDao.findByOwnerAndType(domainId, ResourceOwnerType.Domain, type);
+                long oldCount = domainRC.getCount();
+    
+                List<DomainVO> domainChildren = _domainDao.findImmediateChildrenForParent(domainId);
+                // for each child domain update the resource count
+                if (type.supportsOwner(ResourceOwnerType.Domain)) {
+    
+                    // calculate project count here
+                    if (type == ResourceType.project) {
+                        newCount = newCount + _projectDao.countProjectsForDomain(domainId);
+                    }
+    
+                    for (DomainVO domainChild : domainChildren) {
+                        long domainCount = recalculateDomainResourceCount(domainChild.getId(), type);
+                        newCount = newCount + domainCount; // add the child domain count to parent domain count
+                    }
                 }
-
-                for (DomainVO domainChild : domainChildren) {
-                    long domainCount = recalculateDomainResourceCount(domainChild.getId(), type);
-                    newCount = newCount + domainCount; // add the child domain count to parent domain count
+    
+                if (type.supportsOwner(ResourceOwnerType.Account)) {
+                    List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domainId);
+                    for (AccountVO account : accounts) {
+                        long accountCount = recalculateAccountResourceCount(account.getId(), type);
+                        newCount = newCount + accountCount; // add account's resource count to parent domain count
+                    }
                 }
-            }
-
-            if (type.supportsOwner(ResourceOwnerType.Account)) {
-                List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domainId);
-                for (AccountVO account : accounts) {
-                    long accountCount = recalculateAccountResourceCount(account.getId(), type);
-                    newCount = newCount + accountCount; // add account's resource count to parent domain count
+                _resourceCountDao.setResourceCount(domainId, ResourceOwnerType.Domain, type, newCount);
+    
+                if (oldCount != newCount) {
+                    s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " +
+                            newCount + ") for type " + type + " for domain ID " + domainId + " is fixed during resource count recalculation.");
                 }
+                
+                return newCount;
             }
-            _resourceCountDao.setResourceCount(domainId, ResourceOwnerType.Domain, type, newCount);
-
-            if (oldCount != newCount) {
-                s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " +
-                        newCount + ") for type " + type + " for domain ID " + domainId + " is fixed during resource count recalculation.");
-            }
-        } catch (Exception e) {
-            throw new CloudRuntimeException("Failed to update resource count for domain with Id " + domainId);
-        } finally {
-            txn.commit();
-        }
-
-        return newCount;
+        });
     }
 
     @DB
-    protected long recalculateAccountResourceCount(long accountId, ResourceType type) {
-        Long newCount = null;
-
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-
-        // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table
-        // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too
-        SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
-        sc.setParameters("accountId", accountId);
-        _resourceCountDao.lockRows(sc, null, true);
-
-        ResourceCountVO accountRC = _resourceCountDao.findByOwnerAndType(accountId, ResourceOwnerType.Account, type);
-        long oldCount = 0;
-        if (accountRC != null)
-            oldCount = accountRC.getCount();
-
-        if (type == Resource.ResourceType.user_vm) {
-            newCount = _userVmDao.countAllocatedVMsForAccount(accountId);
-        } else if (type == Resource.ResourceType.volume) {
-            newCount = _volumeDao.countAllocatedVolumesForAccount(accountId);
-            long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size();
-            newCount = newCount - virtualRouterCount; // don't count the volumes of virtual router
-        } else if (type == Resource.ResourceType.snapshot) {
-            newCount = _snapshotDao.countSnapshotsForAccount(accountId);
-        } else if (type == Resource.ResourceType.public_ip) {
-            newCount = calculatePublicIpForAccount(accountId);
-        } else if (type == Resource.ResourceType.template) {
-            newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
-        } else if (type == Resource.ResourceType.project) {
-            newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
-        } else if (type == Resource.ResourceType.network) {
-            newCount = _networkDao.countNetworksUserCanCreate(accountId);
-        } else if (type == Resource.ResourceType.vpc) {
-            newCount = _vpcDao.countByAccountId(accountId);
-        } else if (type == Resource.ResourceType.cpu) {
-            newCount = countCpusForAccount(accountId);
-        } else if (type == Resource.ResourceType.memory) {
-            newCount = calculateMemoryForAccount(accountId);
-        } else if (type == Resource.ResourceType.primary_storage) {
-            List<Long> virtualRouters = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId);
-            newCount = _volumeDao.primaryStorageUsedForAccount(accountId, virtualRouters);
-        } else if (type == Resource.ResourceType.secondary_storage) {
-            newCount = calculateSecondaryStorageForAccount(accountId);
-        } else {
-            throw new InvalidParameterValueException("Unsupported resource type " + type);
-        }
-        _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue());
-
-        if (oldCount != newCount) {
-            s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " +
-                    newCount + ") for type " + type + " for account ID " + accountId + " is fixed during resource count recalculation.");
-        }
-        txn.commit();
+    protected long recalculateAccountResourceCount(final long accountId, final ResourceType type) {
+        Long newCount = Transaction.execute(new TransactionCallback<Long>() {
+            @Override
+            public Long doInTransaction(TransactionStatus status) {
+                Long newCount = null;
+
+                // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table
+                // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too
+                SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
+                sc.setParameters("accountId", accountId);
+                _resourceCountDao.lockRows(sc, null, true);
+        
+                ResourceCountVO accountRC = _resourceCountDao.findByOwnerAndType(accountId, ResourceOwnerType.Account, type);
+                long oldCount = 0;
+                if (accountRC != null)
+                    oldCount = accountRC.getCount();
+        
+                if (type == Resource.ResourceType.user_vm) {
+                    newCount = _userVmDao.countAllocatedVMsForAccount(accountId);
+                } else if (type == Resource.ResourceType.volume) {
+                    newCount = _volumeDao.countAllocatedVolumesForAccount(accountId);
+                    long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size();
+                    newCount = newCount - virtualRouterCount; // don't count the volumes of virtual router
+                } else if (type == Resource.ResourceType.snapshot) {
+                    newCount = _snapshotDao.countSnapshotsForAccount(accountId);
+                } else if (type == Resource.ResourceType.public_ip) {
+                    newCount = calculatePublicIpForAccount(accountId);
+                } else if (type == Resource.ResourceType.template) {
+                    newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
+                } else if (type == Resource.ResourceType.project) {
+                    newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
+                } else if (type == Resource.ResourceType.network) {
+                    newCount = _networkDao.countNetworksUserCanCreate(accountId);
+                } else if (type == Resource.ResourceType.vpc) {
+                    newCount = _vpcDao.countByAccountId(accountId);
+                } else if (type == Resource.ResourceType.cpu) {
+                    newCount = countCpusForAccount(accountId);
+                } else if (type == Resource.ResourceType.memory) {
+                    newCount = calculateMemoryForAccount(accountId);
+                } else if (type == Resource.ResourceType.primary_storage) {
+                    List<Long> virtualRouters = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId);
+                    newCount = _volumeDao.primaryStorageUsedForAccount(accountId, virtualRouters);
+                } else if (type == Resource.ResourceType.secondary_storage) {
+                    newCount = calculateSecondaryStorageForAccount(accountId);
+                } else {
+                    throw new InvalidParameterValueException("Unsupported resource type " + type);
+                }
+                _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue());
+        
+                if (oldCount != newCount) {
+                    s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " +
+                            newCount + ") for type " + type + " for account ID " + accountId + " is fixed during resource count recalculation.");
+                }
+                
+                return newCount;
+            }
+        });
 
         return (newCount == null) ? 0 : newCount.longValue();
     }