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/16 18:50:17 UTC

[06/20] New Transaction API

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index 651e82c..8ab06b8 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -118,9 +118,14 @@ import com.cloud.utils.db.GlobalLock;
 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.Op;
 import com.cloud.utils.db.Transaction;
 import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExceptionUtil;
 import com.cloud.utils.net.NetUtils;
 import com.cloud.vm.ReservationContext;
 import com.cloud.vm.ReservationContextImpl;
@@ -206,50 +211,50 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
     @DB
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
         //configure default vpc offering
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        
-        if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCOfferingName) == null) {
-            s_logger.debug("Creating default VPC offering " + VpcOffering.defaultVPCOfferingName);
-            
-            Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
-            Set<Provider> defaultProviders = new HashSet<Provider>();
-            defaultProviders.add(Provider.VPCVirtualRouter);
-            for (Service svc : getSupportedServices()) {
-                if (svc == Service.Lb) {
-                    Set<Provider> lbProviders = new HashSet<Provider>();
-                    lbProviders.add(Provider.VPCVirtualRouter);
-                    lbProviders.add(Provider.InternalLbVm);
-                    svcProviderMap.put(svc, lbProviders);
-                } else {
-                    svcProviderMap.put(svc, defaultProviders);
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCOfferingName) == null) {
+                    s_logger.debug("Creating default VPC offering " + VpcOffering.defaultVPCOfferingName);
+                    
+                    Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
+                    Set<Provider> defaultProviders = new HashSet<Provider>();
+                    defaultProviders.add(Provider.VPCVirtualRouter);
+                    for (Service svc : getSupportedServices()) {
+                        if (svc == Service.Lb) {
+                            Set<Provider> lbProviders = new HashSet<Provider>();
+                            lbProviders.add(Provider.VPCVirtualRouter);
+                            lbProviders.add(Provider.InternalLbVm);
+                            svcProviderMap.put(svc, lbProviders);
+                        } else {
+                            svcProviderMap.put(svc, defaultProviders);
+                        }
+                    }
+                    createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap,
+                            true, State.Enabled);
                 }
-            }
-            createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap,
-                    true, State.Enabled);
-        }
-
-        //configure default vpc offering with Netscaler as LB Provider
-        if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCNSOfferingName ) == null) {
-            s_logger.debug("Creating default VPC offering with Netscaler as LB Provider" + VpcOffering.defaultVPCNSOfferingName);
-            Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
-            Set<Provider> defaultProviders = new HashSet<Provider>();
-            defaultProviders.add(Provider.VPCVirtualRouter);
-            for (Service svc : getSupportedServices()) {
-                if (svc == Service.Lb) {
-                    Set<Provider> lbProviders = new HashSet<Provider>();
-                    lbProviders.add(Provider.Netscaler);
-                    lbProviders.add(Provider.InternalLbVm);
-                    svcProviderMap.put(svc, lbProviders);
-                } else {
-                    svcProviderMap.put(svc, defaultProviders);
+        
+                //configure default vpc offering with Netscaler as LB Provider
+                if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCNSOfferingName ) == null) {
+                    s_logger.debug("Creating default VPC offering with Netscaler as LB Provider" + VpcOffering.defaultVPCNSOfferingName);
+                    Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
+                    Set<Provider> defaultProviders = new HashSet<Provider>();
+                    defaultProviders.add(Provider.VPCVirtualRouter);
+                    for (Service svc : getSupportedServices()) {
+                        if (svc == Service.Lb) {
+                            Set<Provider> lbProviders = new HashSet<Provider>();
+                            lbProviders.add(Provider.Netscaler);
+                            lbProviders.add(Provider.InternalLbVm);
+                            svcProviderMap.put(svc, lbProviders);
+                        } else {
+                            svcProviderMap.put(svc, defaultProviders);
+                        }
+                    }
+                    createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName,
+                            svcProviderMap, false, State.Enabled);
                 }
             }
-            createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName,
-                    svcProviderMap, false, State.Enabled);
-        }
-
-        txn.commit();
+        });
         
         Map<String, String> configs = _configDao.getConfiguration(params);
         String value = configs.get(Config.VpcCleanupInterval.key());
@@ -375,36 +380,38 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
 
     
     @DB
-    protected VpcOffering createVpcOffering(String name, String displayText, Map<Network.Service,
-            Set<Network.Provider>> svcProviderMap, boolean isDefault, State state) {
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        // create vpc offering object
-        VpcOfferingVO offering  = new VpcOfferingVO(name, displayText, isDefault, null);
-        
-        if (state != null) {
-            offering.setState(state);
-        }
-        s_logger.debug("Adding vpc offering " + offering);
-        offering = _vpcOffDao.persist(offering);
-        // populate services and providers
-        if (svcProviderMap != null) {
-            for (Network.Service service : svcProviderMap.keySet()) {
-                Set<Provider> providers = svcProviderMap.get(service);
-                if (providers != null && !providers.isEmpty()) {
-                    for (Network.Provider provider : providers) {
-                        VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider);
-                        _vpcOffSvcMapDao.persist(offService);
-                        s_logger.trace("Added service for the vpc offering: " + offService + " with provider " + provider.getName());
+    protected VpcOffering createVpcOffering(final String name, final String displayText, final Map<Network.Service,
+            Set<Network.Provider>> svcProviderMap, final boolean isDefault, final State state) {
+        return Transaction.execute(new TransactionCallback<VpcOffering>() {
+            @Override
+            public VpcOffering doInTransaction(TransactionStatus status) {
+                // create vpc offering object
+                VpcOfferingVO offering  = new VpcOfferingVO(name, displayText, isDefault, null);
+
+                if (state != null) {
+                    offering.setState(state);
+                }
+                s_logger.debug("Adding vpc offering " + offering);
+                offering = _vpcOffDao.persist(offering);
+                // populate services and providers
+                if (svcProviderMap != null) {
+                    for (Network.Service service : svcProviderMap.keySet()) {
+                        Set<Provider> providers = svcProviderMap.get(service);
+                        if (providers != null && !providers.isEmpty()) {
+                            for (Network.Provider provider : providers) {
+                                VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider);
+                                _vpcOffSvcMapDao.persist(offService);
+                                s_logger.trace("Added service for the vpc offering: " + offService + " with provider " + provider.getName());
+                            }
+                        } else {
+                            throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName());
+                        }
                     }
-                } else {
-                    throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName());
                 }
-            }
-        }
-        txn.commit();
 
-        return offering;
+                return offering;
+            }
+        });
     }
     
     @Override
@@ -635,14 +642,14 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
 
     
     @DB
-    protected Vpc createVpc(long zoneId, long vpcOffId, Account vpcOwner, String vpcName, String displayText, String cidr,
-            String networkDomain) {
-        
+    protected Vpc createVpc(final long zoneId, final long vpcOffId, final Account vpcOwner, final String vpcName, final String displayText, final String cidr,
+            final String networkDomain) {
+
         //Validate CIDR
         if (!NetUtils.isValidCIDR(cidr)) {
             throw new InvalidParameterValueException("Invalid CIDR specified " + cidr);
         }
-        
+
         //cidr has to be RFC 1918 complient
         if (!NetUtils.validateGuestCidr(cidr)) {
             throw new InvalidParameterValueException("Guest Cidr " + cidr + " is not RFC1918 compliant");
@@ -657,17 +664,19 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
                             + "and the hyphen ('-'); can't start or end with \"-\"");
         }
 
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        VpcVO vpc = new VpcVO (zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId, cidr,
-                networkDomain);
-        vpc = _vpcDao.persist(vpc, finalizeServicesAndProvidersForVpc(zoneId, vpcOffId));
-        _resourceLimitMgr.incrementResourceCount(vpcOwner.getId(), ResourceType.vpc);
-        txn.commit();
+        return Transaction.execute(new TransactionCallback<VpcVO>() {
+            @Override
+            public VpcVO doInTransaction(TransactionStatus status) {
+                VpcVO vpc = new VpcVO (zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId, cidr,
+                        networkDomain);
+                vpc = _vpcDao.persist(vpc, finalizeServicesAndProvidersForVpc(zoneId, vpcOffId));
+                _resourceLimitMgr.incrementResourceCount(vpcOwner.getId(), ResourceType.vpc);
 
-        s_logger.debug("Created VPC " + vpc);
+                s_logger.debug("Created VPC " + vpc);
 
-        return vpc;
+                return vpc;
+            }
+        });
     }
 
     private Map<String, List<String>> finalizeServicesAndProvidersForVpc(long zoneId, long offeringId) {
@@ -722,7 +731,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
 
     @Override
     @DB
-    public boolean destroyVpc(Vpc vpc, Account caller, Long callerUserId) throws ConcurrentOperationException, ResourceUnavailableException {
+    public boolean destroyVpc(final Vpc vpc, Account caller, Long callerUserId) throws ConcurrentOperationException, ResourceUnavailableException {
         s_logger.debug("Destroying vpc " + vpc);
         
         //don't allow to delete vpc if it's in use by existing non system networks (system networks are networks of a private gateway of the VPC,
@@ -735,16 +744,18 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         //mark VPC as inactive
         if (vpc.getState() != Vpc.State.Inactive) {
             s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Inactive + " as a part of vpc delete");
-            VpcVO vpcVO = _vpcDao.findById(vpc.getId());
+            final VpcVO vpcVO = _vpcDao.findById(vpc.getId());
             vpcVO.setState(Vpc.State.Inactive);
             
-            Transaction txn = Transaction.currentTxn();
-            txn.start();
-            _vpcDao.update(vpc.getId(), vpcVO);
-            
-            //decrement resource count
-            _resourceLimitMgr.decrementResourceCount(vpc.getAccountId(), ResourceType.vpc);
-            txn.commit();
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    _vpcDao.update(vpc.getId(), vpcVO);
+
+                    //decrement resource count
+                    _resourceLimitMgr.decrementResourceCount(vpc.getAccountId(), ResourceType.vpc);
+                }
+            });
         }
         
         //shutdown VPC
@@ -1140,67 +1151,68 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
     }
 
     @DB
-    protected void validateNewVpcGuestNetwork(String cidr, String gateway, Account networkOwner, Vpc vpc, String networkDomain) {
-        
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        Vpc locked = _vpcDao.acquireInLockTable(vpc.getId());
-        if (locked == null) {
-            throw new CloudRuntimeException("Unable to acquire lock on " + vpc);
-        }
-        
-        try {
-            //check number of active networks in vpc
-            if (_ntwkDao.countVpcNetworks(vpc.getId()) >= _maxNetworks) {
-                throw new CloudRuntimeException("Number of networks per VPC can't extend "
-                        + _maxNetworks + "; increase it using global config " + Config.VpcMaxNetworks);
-            }
-            
-            
-            //1) CIDR is required
-            if (cidr == null) {
-                throw new InvalidParameterValueException("Gateway/netmask are required when create network for VPC");
-            }
-            
-            //2) Network cidr should be within vpcCidr
-            if (!NetUtils.isNetworkAWithinNetworkB(cidr, vpc.getCidr())) {
-                throw new InvalidParameterValueException("Network cidr " + cidr + " is not within vpc " + vpc + " cidr");
-            }
-            
-            //3) Network cidr shouldn't cross the cidr of other vpc network cidrs
-            List<? extends Network> ntwks = _ntwkDao.listByVpc(vpc.getId());
-            for (Network ntwk : ntwks) {
-                assert (cidr != null) : "Why the network cidr is null when it belongs to vpc?";
+    protected void validateNewVpcGuestNetwork(final String cidr, final String gateway, final Account networkOwner, final Vpc vpc, final String networkDomain) {
+        
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                Vpc locked = _vpcDao.acquireInLockTable(vpc.getId());
+                if (locked == null) {
+                    throw new CloudRuntimeException("Unable to acquire lock on " + vpc);
+                }
                 
-                if (NetUtils.isNetworkAWithinNetworkB(ntwk.getCidr(), cidr)
-                        || NetUtils.isNetworkAWithinNetworkB(cidr, ntwk.getCidr())) {
-                    throw new InvalidParameterValueException("Network cidr " + cidr + " crosses other network cidr " + ntwk +
-                            " belonging to the same vpc " + vpc);
+                try {
+                    //check number of active networks in vpc
+                    if (_ntwkDao.countVpcNetworks(vpc.getId()) >= _maxNetworks) {
+                        throw new CloudRuntimeException("Number of networks per VPC can't extend "
+                                + _maxNetworks + "; increase it using global config " + Config.VpcMaxNetworks);
+                    }
+                    
+                    
+                    //1) CIDR is required
+                    if (cidr == null) {
+                        throw new InvalidParameterValueException("Gateway/netmask are required when create network for VPC");
+                    }
+                    
+                    //2) Network cidr should be within vpcCidr
+                    if (!NetUtils.isNetworkAWithinNetworkB(cidr, vpc.getCidr())) {
+                        throw new InvalidParameterValueException("Network cidr " + cidr + " is not within vpc " + vpc + " cidr");
+                    }
+                    
+                    //3) Network cidr shouldn't cross the cidr of other vpc network cidrs
+                    List<? extends Network> ntwks = _ntwkDao.listByVpc(vpc.getId());
+                    for (Network ntwk : ntwks) {
+                        assert (cidr != null) : "Why the network cidr is null when it belongs to vpc?";
+                        
+                        if (NetUtils.isNetworkAWithinNetworkB(ntwk.getCidr(), cidr)
+                                || NetUtils.isNetworkAWithinNetworkB(cidr, ntwk.getCidr())) {
+                            throw new InvalidParameterValueException("Network cidr " + cidr + " crosses other network cidr " + ntwk +
+                                    " belonging to the same vpc " + vpc);
+                        }
+                    }
+                    
+                    //4) vpc and network should belong to the same owner
+                    if (vpc.getAccountId() != networkOwner.getId()) {
+                        throw new InvalidParameterValueException("Vpc " + vpc + " owner is different from the network owner "
+                                + networkOwner);
+                    }
+                    
+                    //5) network domain should be the same as VPC's
+                    if (!networkDomain.equalsIgnoreCase(vpc.getNetworkDomain())) {
+                        throw new InvalidParameterValueException("Network domain of the new network should match network" +
+                        		" domain of vpc " + vpc);
+                    }
+                    
+                    //6) gateway should never be equal to the cidr subnet
+                    if (NetUtils.getCidrSubNet(cidr).equalsIgnoreCase(gateway)) {
+                        throw new InvalidParameterValueException("Invalid gateway specified. It should never be equal to the cidr subnet value");
+                    }
+                } finally {
+                    s_logger.debug("Releasing lock for " + locked);
+                    _vpcDao.releaseFromLockTable(locked.getId());
                 }
             }
-            
-            //4) vpc and network should belong to the same owner
-            if (vpc.getAccountId() != networkOwner.getId()) {
-                throw new InvalidParameterValueException("Vpc " + vpc + " owner is different from the network owner "
-                        + networkOwner);
-            }
-            
-            //5) network domain should be the same as VPC's
-            if (!networkDomain.equalsIgnoreCase(vpc.getNetworkDomain())) {
-                throw new InvalidParameterValueException("Network domain of the new network should match network" +
-                		" domain of vpc " + vpc);
-            }
-            
-            //6) gateway should never be equal to the cidr subnet
-            if (NetUtils.getCidrSubNet(cidr).equalsIgnoreCase(gateway)) {
-                throw new InvalidParameterValueException("Invalid gateway specified. It should never be equal to the cidr subnet value");
-            }
-
-            txn.commit();
-        } finally {
-            s_logger.debug("Releasing lock for " + locked);
-            _vpcDao.releaseFromLockTable(locked.getId());
-        }
+        });
     }
 
 
@@ -1361,12 +1373,12 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
     @Override
     @DB
     @ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_CREATE, eventDescription = "creating vpc private gateway", create=true)
-    public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String broadcastUri, String ipAddress,
-            String gateway, String netmask, long gatewayOwnerId, Long networkOfferingId, Boolean isSourceNat, Long aclId) throws ResourceAllocationException,
+    public PrivateGateway createVpcPrivateGateway(final long vpcId, Long physicalNetworkId, final String broadcastUri, final String ipAddress,
+            final String gateway, final String netmask, final long gatewayOwnerId, final Long networkOfferingId, final Boolean isSourceNat, final Long aclId) throws ResourceAllocationException,
             ConcurrentOperationException, InsufficientCapacityException {
         
         //Validate parameters
-        Vpc vpc = getActiveVpc(vpcId);
+        final Vpc vpc = getActiveVpc(vpcId);
         if (vpc == null) {
             InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified");
             ex.addProxyObject(String.valueOf(vpcId), "VPC");
@@ -1387,66 +1399,79 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         if (physNet == null) {
             physNet = _entityMgr.findById(PhysicalNetwork.class,physicalNetworkId);
         }
-        Long dcId = physNet.getDataCenterId();
-        
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        s_logger.debug("Creating Private gateway for VPC " + vpc);
-        //1) create private network unless it is existing and lswitch'd
-        Network privateNtwk = null;
-        if (BroadcastDomainType.getSchemeValue(BroadcastDomainType.fromString(broadcastUri)) == BroadcastDomainType.Lswitch) {
-            String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
-
-            privateNtwk = _ntwkDao.getPrivateNetwork(broadcastUri, cidr,
-                    gatewayOwnerId, dcId, networkOfferingId);
-            s_logger.info("found and using existing network for vpc " + vpc + ": " + broadcastUri);
-        }
-        if (privateNtwk == null) {
-            s_logger.info("creating new network for vpc " + vpc + " using broadcast uri: " + broadcastUri);
-            String networkName = "vpc-" + vpc.getName() + "-privateNetwork";
-            privateNtwk = _ntwkSvc.createPrivateNetwork(networkName, networkName, physicalNetworkId, 
-                broadcastUri, ipAddress, null, gateway, netmask, gatewayOwnerId, vpcId, isSourceNat, networkOfferingId);
-        } else { // create the nic/ip as createPrivateNetwork doesn''t do that work for us now
-            DataCenterVO dc = _dcDao.lockRow(physNet.getDataCenterId(), true);
-
-            //add entry to private_ip_address table
-            PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkId(privateNtwk.getId(), ipAddress);
-            if (privateIp != null) {
-                throw new InvalidParameterValueException("Private ip address " + ipAddress + " already used for private gateway" +
-                        " in zone " + _entityMgr.findById(DataCenter.class,dcId).getName());
-            }
-
-            Long mac = dc.getMacAddress();
-            Long nextMac = mac + 1;
-            dc.setMacAddress(nextMac);
-
-            privateIp = new PrivateIpVO(ipAddress, privateNtwk.getId(), nextMac, vpcId, true);
-            _privateIpDao.persist(privateIp);
-
-            _dcDao.update(dc.getId(), dc);
-        }
-
-        long networkAclId = NetworkACL.DEFAULT_DENY;
-        if (aclId != null) {
-            NetworkACLVO aclVO = _networkAclDao.findById(aclId);
-            if ( aclVO == null) {
-                throw new InvalidParameterValueException("Invalid network acl id passed ");
-            }
-            if ((aclVO.getVpcId() != vpcId) && !(aclId == NetworkACL.DEFAULT_DENY || aclId == NetworkACL.DEFAULT_ALLOW)) {
-                throw new InvalidParameterValueException("Private gateway and network acl are not in the same vpc");
-            }
-
-            networkAclId = aclId;
-        }
-
-        //2) create gateway entry
-        VpcGatewayVO gatewayVO = new VpcGatewayVO(ipAddress, VpcGateway.Type.Private, vpcId, privateNtwk.getDataCenterId(),
-                privateNtwk.getId(), broadcastUri, gateway, netmask, vpc.getAccountId(), vpc.getDomainId(), isSourceNat, networkAclId);
-        _vpcGatewayDao.persist(gatewayVO);
-        
-        s_logger.debug("Created vpc gateway entry " + gatewayVO);
+        final Long dcId = physNet.getDataCenterId();
         
-        txn.commit();
+        final Long physicalNetworkIdFinal = physicalNetworkId;
+        final PhysicalNetwork physNetFinal = physNet;
+        VpcGatewayVO gatewayVO = null;
+        try {
+            gatewayVO = Transaction.executeWithException(new TransactionCallbackWithException<VpcGatewayVO>() {
+                @Override
+                public VpcGatewayVO doInTransaction(TransactionStatus status) throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
+                    s_logger.debug("Creating Private gateway for VPC " + vpc);
+                    //1) create private network unless it is existing and lswitch'd
+                    Network privateNtwk = null;
+                    if (BroadcastDomainType.getSchemeValue(BroadcastDomainType.fromString(broadcastUri)) == BroadcastDomainType.Lswitch) {
+                        String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
+            
+                        privateNtwk = _ntwkDao.getPrivateNetwork(broadcastUri, cidr,
+                                gatewayOwnerId, dcId, networkOfferingId);
+                        s_logger.info("found and using existing network for vpc " + vpc + ": " + broadcastUri);
+                    }
+                    if (privateNtwk == null) {
+                        s_logger.info("creating new network for vpc " + vpc + " using broadcast uri: " + broadcastUri);
+                        String networkName = "vpc-" + vpc.getName() + "-privateNetwork";
+                        privateNtwk = _ntwkSvc.createPrivateNetwork(networkName, networkName, physicalNetworkIdFinal, 
+                            broadcastUri, ipAddress, null, gateway, netmask, gatewayOwnerId, vpcId, isSourceNat, networkOfferingId);
+                    } else { // create the nic/ip as createPrivateNetwork doesn''t do that work for us now
+                        DataCenterVO dc = _dcDao.lockRow(physNetFinal.getDataCenterId(), true);
+            
+                        //add entry to private_ip_address table
+                        PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkId(privateNtwk.getId(), ipAddress);
+                        if (privateIp != null) {
+                            throw new InvalidParameterValueException("Private ip address " + ipAddress + " already used for private gateway" +
+                                    " in zone " + _entityMgr.findById(DataCenter.class,dcId).getName());
+                        }
+            
+                        Long mac = dc.getMacAddress();
+                        Long nextMac = mac + 1;
+                        dc.setMacAddress(nextMac);
+            
+                        privateIp = new PrivateIpVO(ipAddress, privateNtwk.getId(), nextMac, vpcId, true);
+                        _privateIpDao.persist(privateIp);
+            
+                        _dcDao.update(dc.getId(), dc);
+                    }
+            
+                    long networkAclId = NetworkACL.DEFAULT_DENY;
+                    if (aclId != null) {
+                        NetworkACLVO aclVO = _networkAclDao.findById(aclId);
+                        if ( aclVO == null) {
+                            throw new InvalidParameterValueException("Invalid network acl id passed ");
+                        }
+                        if ((aclVO.getVpcId() != vpcId) && !(aclId == NetworkACL.DEFAULT_DENY || aclId == NetworkACL.DEFAULT_ALLOW)) {
+                            throw new InvalidParameterValueException("Private gateway and network acl are not in the same vpc");
+                        }
+            
+                        networkAclId = aclId;
+                    }
+            
+                    //2) create gateway entry
+                    VpcGatewayVO gatewayVO = new VpcGatewayVO(ipAddress, VpcGateway.Type.Private, vpcId, privateNtwk.getDataCenterId(),
+                            privateNtwk.getId(), broadcastUri, gateway, netmask, vpc.getAccountId(), vpc.getDomainId(), isSourceNat, networkAclId);
+                    _vpcGatewayDao.persist(gatewayVO);
+                    
+                    s_logger.debug("Created vpc gateway entry " + gatewayVO);
+                    
+                    return gatewayVO;
+                }
+            }, Exception.class);
+        } catch (Exception e) {
+            ExceptionUtil.rethrowRuntime(e);
+            ExceptionUtil.rethrow(e, InsufficientCapacityException.class);
+            ExceptionUtil.rethrow(e, ResourceAllocationException.class);
+            throw new IllegalStateException(e);
+        }
         
         return getVpcPrivateGateway(gatewayVO.getId());
     }
@@ -1496,26 +1521,28 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
     @DB
     public boolean deleteVpcPrivateGateway(long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException {
         
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        VpcGatewayVO gatewayVO = _vpcGatewayDao.acquireInLockTable(gatewayId);
+        final VpcGatewayVO gatewayVO = _vpcGatewayDao.acquireInLockTable(gatewayId);
         if (gatewayVO == null || gatewayVO.getType() != VpcGateway.Type.Private) {
             throw new ConcurrentOperationException("Unable to lock gateway " + gatewayId);
         }
 
         try {
-            //don't allow to remove gateway when there are static routes associated with it
-            long routeCount = _staticRouteDao.countRoutesByGateway(gatewayVO.getId());
-            if (routeCount > 0) {
-                throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount +
-                        " static routes applied. Remove the routes first");
-            }
-            
-            gatewayVO.setState(VpcGateway.State.Deleting);
-            _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO);
-            s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Deleting);
-            
-            txn.commit();
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    //don't allow to remove gateway when there are static routes associated with it
+                    long routeCount = _staticRouteDao.countRoutesByGateway(gatewayVO.getId());
+                    if (routeCount > 0) {
+                        throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount +
+                                " static routes applied. Remove the routes first");
+                    }
+
+                    gatewayVO.setState(VpcGateway.State.Deleting);
+                    _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO);
+                    s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Deleting);
+                }
+            });
+
 
             //1) delete the gateway on the backend
             PrivateGateway gateway = getVpcPrivateGateway(gatewayId);
@@ -1539,9 +1566,9 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
     }
     
     @DB
-    protected boolean deletePrivateGatewayFromTheDB(PrivateGateway gateway) {
+    protected boolean deletePrivateGatewayFromTheDB(final PrivateGateway gateway) {
         //check if there are ips allocted in the network
-        long networkId = gateway.getNetworkId();
+        final long networkId = gateway.getNetworkId();
         
         boolean deleteNetwork = true;
         List<PrivateIpVO> privateIps = _privateIpDao.listByNetworkId(networkId);
@@ -1550,27 +1577,31 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
             deleteNetwork = false;
         }
         
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        
-        PrivateIpVO ip = _privateIpDao.findByIpAndVpcId(gateway.getVpcId(), gateway.getIp4Address());
-        if (ip != null) {
-            _privateIpDao.remove(ip.getId());
-            s_logger.debug("Deleted private ip " + ip);
-        }
-        
-        if (deleteNetwork) {
-            User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
-            Account owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
-            ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner);
-            _ntwkMgr.destroyNetwork(networkId, context);
-            s_logger.debug("Deleted private network id=" + networkId);
-        }
-        
-        _vpcGatewayDao.remove(gateway.getId());
-        s_logger.debug("Deleted private gateway " + gateway);
+        //TODO: Clean this up, its bad.  There is a DB transaction wrapping calls to NetworkElements (destroyNetwork will
+        // call network elements).
+        final boolean deleteNetworkFinal = deleteNetwork;
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                PrivateIpVO ip = _privateIpDao.findByIpAndVpcId(gateway.getVpcId(), gateway.getIp4Address());
+                if (ip != null) {
+                    _privateIpDao.remove(ip.getId());
+                    s_logger.debug("Deleted private ip " + ip);
+                }
+                
+                if (deleteNetworkFinal) {
+                    User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
+                    Account owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
+                    ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner);
+                    _ntwkMgr.destroyNetwork(networkId, context);
+                    s_logger.debug("Deleted private network id=" + networkId);
+                }
+                
+                _vpcGatewayDao.remove(gateway.getId());
+                s_logger.debug("Deleted private gateway " + gateway);
+            }
+        });
         
-        txn.commit();
         return true;
     }
 
@@ -1729,18 +1760,20 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
     }
     
     @DB
-    protected boolean revokeStaticRoutesForVpc(long vpcId, Account caller) throws ResourceUnavailableException {
+    protected boolean revokeStaticRoutesForVpc(long vpcId, final Account caller) throws ResourceUnavailableException {
         //get all static routes for the vpc
-        List<StaticRouteVO> routes = _staticRouteDao.listByVpcId(vpcId);
+        final List<StaticRouteVO> routes = _staticRouteDao.listByVpcId(vpcId);
         s_logger.debug("Found " + routes.size() + " to revoke for the vpc " + vpcId);
         if (!routes.isEmpty()) {
             //mark all of them as revoke
-            Transaction txn = Transaction.currentTxn();
-            txn.start();
-            for (StaticRouteVO route : routes) {
-                markStaticRouteForRevoke(route, caller);
-            }
-            txn.commit();
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    for (StaticRouteVO route : routes) {
+                        markStaticRouteForRevoke(route, caller);
+                    }
+                }
+            });
             return applyStaticRoutes(vpcId);
         }
         
@@ -1750,11 +1783,11 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
     @Override
     @DB
     @ActionEvent(eventType = EventTypes.EVENT_STATIC_ROUTE_CREATE, eventDescription = "creating static route", create=true)
-    public StaticRoute createStaticRoute(long gatewayId, String cidr) throws NetworkRuleConflictException {
+    public StaticRoute createStaticRoute(long gatewayId, final String cidr) throws NetworkRuleConflictException {
         Account caller = CallContext.current().getCallingAccount();
         
         //parameters validation
-        VpcGateway gateway = _vpcGatewayDao.findById(gatewayId);
+        final VpcGateway gateway = _vpcGatewayDao.findById(gatewayId);
         if (gateway == null) {
             throw new InvalidParameterValueException("Invalid gateway id is given");
         }
@@ -1763,7 +1796,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
             throw new InvalidParameterValueException("Gateway is not in the " + VpcGateway.State.Ready + " state: " + gateway.getState());
         }
         
-        Vpc vpc = getActiveVpc(gateway.getVpcId());
+        final Vpc vpc = getActiveVpc(gateway.getVpcId());
         if (vpc == null) {
             throw new InvalidParameterValueException("Can't add static route to VPC that is being deleted");
         }
@@ -1789,23 +1822,23 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
             throw new InvalidParameterValueException("The static gateway cidr overlaps with one of the blacklisted routes of the zone the VPC belongs to");
         }
 
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        
-        StaticRouteVO newRoute = new StaticRouteVO(gateway.getId(), cidr, vpc.getId(), vpc.getAccountId(), vpc.getDomainId());
-        s_logger.debug("Adding static route " + newRoute);
-        newRoute = _staticRouteDao.persist(newRoute);
-        
-        detectRoutesConflict(newRoute);
-
-        if (!_staticRouteDao.setStateToAdd(newRoute)) {
-            throw new CloudRuntimeException("Unable to update the state to add for " + newRoute);
-        }
-        CallContext.current().setEventDetails("Static route Id: " + newRoute.getId());
+        return Transaction.executeWithException(new TransactionCallbackWithException<StaticRouteVO>() {
+            @Override
+            public StaticRouteVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
+                StaticRouteVO newRoute = new StaticRouteVO(gateway.getId(), cidr, vpc.getId(), vpc.getAccountId(), vpc.getDomainId());
+                s_logger.debug("Adding static route " + newRoute);
+                newRoute = _staticRouteDao.persist(newRoute);
+                
+                detectRoutesConflict(newRoute);
         
-        txn.commit();
-
-        return newRoute;
+                if (!_staticRouteDao.setStateToAdd(newRoute)) {
+                    throw new CloudRuntimeException("Unable to update the state to add for " + newRoute);
+                }
+                CallContext.current().setEventDetails("Static route Id: " + newRoute.getId());
+                
+                return newRoute;
+            }
+        }, NetworkRuleConflictException.class);
     }
 
     protected boolean isCidrBlacklisted(String cidr, long zoneId) {
@@ -1947,23 +1980,24 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
                     return;
                 }
 
-                Transaction txn = null;
                 try {
-                    txn = Transaction.open(Transaction.CLOUD_DB);
-
-                    // Cleanup inactive VPCs
-                    List<VpcVO> inactiveVpcs = _vpcDao.listInactiveVpcs();
-                    s_logger.info("Found " + inactiveVpcs.size() + " removed VPCs to cleanup");
-                    for (VpcVO vpc : inactiveVpcs) {
-                        s_logger.debug("Cleaning up " + vpc);
-                        destroyVpc(vpc, _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM);
-                    }
+                    Transaction.executeWithException(new TransactionCallbackWithException<Object>() {
+                        @Override
+                        public Object doInTransaction(TransactionStatus status) throws Exception {
+                            // Cleanup inactive VPCs
+                            List<VpcVO> inactiveVpcs = _vpcDao.listInactiveVpcs();
+                            s_logger.info("Found " + inactiveVpcs.size() + " removed VPCs to cleanup");
+                            for (VpcVO vpc : inactiveVpcs) {
+                                s_logger.debug("Cleaning up " + vpc);
+                                destroyVpc(vpc, _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM);
+                            }
+                            
+                            return null;
+                        }
+                    }, Exception.class);
                 } catch (Exception e) {
                     s_logger.error("Exception ", e);
                 } finally {
-                    if (txn != null) {
-                        txn.close();
-                    }
                     lock.unlock();
                 }
             } catch (Exception e) {
@@ -1976,7 +2010,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
     @DB
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true)
-    public IpAddress associateIPToVpc(long ipId, long vpcId) throws ResourceAllocationException, ResourceUnavailableException,
+    public IpAddress associateIPToVpc(final long ipId, final long vpcId) throws ResourceAllocationException, ResourceUnavailableException,
     InsufficientAddressCapacityException, ConcurrentOperationException {
         Account caller = CallContext.current().getCallingAccount();
         Account owner = null;
@@ -2005,17 +2039,20 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
 
         s_logger.debug("Associating ip " + ipToAssoc + " to vpc " + vpc);
 
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        IPAddressVO ip = _ipAddressDao.findById(ipId);
-        //update ip address with networkId
-        ip.setVpcId(vpcId);
-        ip.setSourceNat(isSourceNat);
-        _ipAddressDao.update(ipId, ip);
-
-        //mark ip as allocated
-        _ipAddrMgr.markPublicIpAsAllocated(ip);
-        txn.commit();
+        final boolean isSourceNatFinal = isSourceNat; 
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                IPAddressVO ip = _ipAddressDao.findById(ipId);
+                //update ip address with networkId
+                ip.setVpcId(vpcId);
+                ip.setSourceNat(isSourceNatFinal);
+                _ipAddressDao.update(ipId, ip);
+
+                //mark ip as allocated
+                _ipAddrMgr.markPublicIpAsAllocated(ip);
+            }
+        });
 
         s_logger.debug("Successfully assigned ip " + ipToAssoc + " to vpc " + vpc);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
index 6cd164d..7912df4 100755
--- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
+++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
@@ -26,7 +26,6 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.command.user.vpn.ListRemoteAccessVpnsCmd;
 import org.apache.cloudstack.api.command.user.vpn.ListVpnUsersCmd;
 import org.apache.cloudstack.context.CallContext;
@@ -80,8 +79,12 @@ import com.cloud.utils.db.Filter;
 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.SearchCriteria.Op;
 import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.net.NetUtils;
 
 @Local(value = RemoteAccessVpnService.class)
@@ -114,13 +117,13 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc
 
     @Override
     @DB
-    public RemoteAccessVpn createRemoteAccessVpn(long publicIpId, String ipRange, boolean openFirewall, long networkId)
+    public RemoteAccessVpn createRemoteAccessVpn(final long publicIpId, String ipRange, final boolean openFirewall, long networkId)
             throws NetworkRuleConflictException {
         CallContext ctx = CallContext.current();
-        Account caller = ctx.getCallingAccount();
+        final Account caller = ctx.getCallingAccount();
 
         // make sure ip address exists
-        PublicIpAddress ipAddr = _networkMgr.getPublicIpAddress(publicIpId);
+        final PublicIpAddress ipAddr = _networkMgr.getPublicIpAddress(publicIpId);
         if (ipAddr == null) {
             throw new InvalidParameterValueException("Unable to create remote access vpn, invalid public IP address id" + publicIpId);
         }
@@ -163,7 +166,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc
         if (ipRange == null) {
             ipRange = RemoteAccessVpnClientIpRange.valueIn(ipAddr.getAccountId());
         }
-        String[] range = ipRange.split("-");
+        final String[] range = ipRange.split("-");
         if (range.length != 2) {
             throw new InvalidParameterValueException("Invalid ip range");
         }
@@ -187,19 +190,18 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc
         // TODO: check overlap with private and public ip ranges in datacenter
 
         long startIp = NetUtils.ip2Long(range[0]);
-        String newIpRange = NetUtils.long2Ip(++startIp) + "-" + range[1];
-        String sharedSecret = PasswordGenerator.generatePresharedKey(_pskLength);
-        
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        
-        _rulesMgr.reservePorts(ipAddr, NetUtils.UDP_PROTO, Purpose.Vpn, openFirewall, caller, NetUtils.VPN_PORT, NetUtils.VPN_L2TP_PORT, NetUtils.VPN_NATT_PORT);
-        vpnVO = new RemoteAccessVpnVO(ipAddr.getAccountId(), ipAddr.getDomainId(), ipAddr.getAssociatedWithNetworkId(),
-                publicIpId, range[0], newIpRange, sharedSecret);
-        RemoteAccessVpn vpn = _remoteAccessVpnDao.persist(vpnVO);
+        final String newIpRange = NetUtils.long2Ip(++startIp) + "-" + range[1];
+        final String sharedSecret = PasswordGenerator.generatePresharedKey(_pskLength);
         
-        txn.commit();
-        return vpn;
+        return Transaction.executeWithException(new TransactionCallbackWithException<RemoteAccessVpn>() {
+            @Override
+            public RemoteAccessVpn doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
+                _rulesMgr.reservePorts(ipAddr, NetUtils.UDP_PROTO, Purpose.Vpn, openFirewall, caller, NetUtils.VPN_PORT, NetUtils.VPN_L2TP_PORT, NetUtils.VPN_NATT_PORT);
+                RemoteAccessVpnVO vpnVO = new RemoteAccessVpnVO(ipAddr.getAccountId(), ipAddr.getDomainId(), ipAddr.getAssociatedWithNetworkId(),
+                        publicIpId, range[0], newIpRange, sharedSecret);
+                return _remoteAccessVpnDao.persist(vpnVO);
+            }
+        }, NetworkRuleConflictException.class);
     }
 
     private void validateRemoteAccessVpnConfiguration() throws ConfigurationException {
@@ -230,7 +232,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc
 
     @Override @DB
     public void destroyRemoteAccessVpnForIp(long ipId, Account caller) throws ResourceUnavailableException {
-        RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByPublicIpAddress(ipId);
+        final RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByPublicIpAddress(ipId);
         if (vpn == null) {
             s_logger.debug("there are no Remote access vpns for public ip address id=" + ipId);
             return;
@@ -255,28 +257,28 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc
         } finally {
             if (success) {
                 //Cleanup corresponding ports
-                List<? extends FirewallRule> vpnFwRules = _rulesDao.listByIpAndPurpose(ipId, Purpose.Vpn);
-                Transaction txn = Transaction.currentTxn();
+                final List<? extends FirewallRule> vpnFwRules = _rulesDao.listByIpAndPurpose(ipId, Purpose.Vpn);
 
                 boolean applyFirewall = false;
-                List<FirewallRuleVO> fwRules = new ArrayList<FirewallRuleVO>();
+                final List<FirewallRuleVO> fwRules = new ArrayList<FirewallRuleVO>();
                 //if related firewall rule is created for the first vpn port, it would be created for the 2 other ports as well, so need to cleanup the backend
                 if (_rulesDao.findByRelatedId(vpnFwRules.get(0).getId()) != null) {
                     applyFirewall = true;
                 }
 
                 if (applyFirewall) {
-                    txn.start();
-
-                    for (FirewallRule vpnFwRule : vpnFwRules) {
-                        //don't apply on the backend yet; send all 3 rules in a banch
-                        _firewallMgr.revokeRelatedFirewallRule(vpnFwRule.getId(), false);
-                        fwRules.add(_rulesDao.findByRelatedId(vpnFwRule.getId()));
-                    }
-
-                    s_logger.debug("Marked " + fwRules.size() + " firewall rules as Revoked as a part of disable remote access vpn");
-
-                    txn.commit();
+                    Transaction.execute(new TransactionCallbackNoReturn() {
+                        @Override
+                        public void doInTransactionWithoutResult(TransactionStatus status) {
+                            for (FirewallRule vpnFwRule : vpnFwRules) {
+                                //don't apply on the backend yet; send all 3 rules in a banch
+                                _firewallMgr.revokeRelatedFirewallRule(vpnFwRule.getId(), false);
+                                fwRules.add(_rulesDao.findByRelatedId(vpnFwRule.getId()));
+                            }
+        
+                            s_logger.debug("Marked " + fwRules.size() + " firewall rules as Revoked as a part of disable remote access vpn");
+                        }
+                    });
 
                     //now apply vpn rules on the backend
                     s_logger.debug("Reapplying firewall rules for ip id=" + ipId + " as a part of disable remote access vpn");
@@ -285,26 +287,28 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc
 
                 if (success) {
                     try {
-                        txn.start();
-                        _remoteAccessVpnDao.remove(vpn.getId());
-                        // Stop billing of VPN users when VPN is removed. VPN_User_ADD events will be generated when VPN is created again
-                        List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId());
-                        for(VpnUserVO user : vpnUsers){
-                            // VPN_USER_REMOVE event is already generated for users in Revoke state
-                            if(user.getState() != VpnUser.State.Revoke){
-                                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(),
-                                        0, user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid());
-                            }
-                        }
-                        if (vpnFwRules != null) {
-                            for (FirewallRule vpnFwRule : vpnFwRules) {
-                                _rulesDao.remove(vpnFwRule.getId());
-                                s_logger.debug("Successfully removed firewall rule with ip id=" + vpnFwRule.getSourceIpAddressId() + " and port " + vpnFwRule.getSourcePortStart() + " as a part of vpn cleanup");
+                        Transaction.execute(new TransactionCallbackNoReturn() {
+                            @Override
+                            public void doInTransactionWithoutResult(TransactionStatus status) {
+                                _remoteAccessVpnDao.remove(vpn.getId());
+                                // Stop billing of VPN users when VPN is removed. VPN_User_ADD events will be generated when VPN is created again
+                                List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId());
+                                for(VpnUserVO user : vpnUsers){
+                                    // VPN_USER_REMOVE event is already generated for users in Revoke state
+                                    if(user.getState() != VpnUser.State.Revoke){
+                                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(),
+                                                0, user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid());
+                                    }
+                                }
+                                if (vpnFwRules != null) {
+                                    for (FirewallRule vpnFwRule : vpnFwRules) {
+                                        _rulesDao.remove(vpnFwRule.getId());
+                                        s_logger.debug("Successfully removed firewall rule with ip id=" + vpnFwRule.getSourceIpAddressId() + " and port " + vpnFwRule.getSourcePortStart() + " as a part of vpn cleanup");
+                                    }
+                                }
                             }
-                        }
-                        txn.commit();
+                        });
                     } catch (Exception ex) {
-                        txn.rollback();
                         s_logger.warn("Unable to release the three vpn ports from the firewall rules", ex);
                     }
                 }
@@ -314,8 +318,8 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc
 
     @Override
     @DB
-    public VpnUser addVpnUser(long vpnOwnerId, String username, String password) {
-        Account caller = CallContext.current().getCallingAccount();
+    public VpnUser addVpnUser(final long vpnOwnerId, final String username, final String password) {
+        final Account caller = CallContext.current().getCallingAccount();
 
         if (!username.matches("^[a-zA-Z0-9][a-zA-Z0-9@._-]{2,63}$")) {
             throw new InvalidParameterValueException(
@@ -324,46 +328,54 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc
         if (!password.matches("^[a-zA-Z0-9][a-zA-Z0-9@#+=._-]{2,31}$")) {
             throw new InvalidParameterValueException("Password has to be 3-32 characters including alphabets, numbers and the set '@#+=.-_'");
         }
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        Account owner = _accountDao.lockRow(vpnOwnerId, true);
-        if (owner == null) {
-            throw new InvalidParameterValueException("Unable to add vpn user: Another operation active");
-        }
-        _accountMgr.checkAccess(caller, null, true, owner);
 
-        //don't allow duplicated user names for the same account
-        VpnUserVO vpnUser = _vpnUsersDao.findByAccountAndUsername(owner.getId(), username);
-        if (vpnUser != null) {
-            throw new InvalidParameterValueException("VPN User with name " + username + " is already added for account " + owner);
-        }
-
-        long userCount = _vpnUsersDao.getVpnUserCount(owner.getId());
-        if (userCount >= _userLimit) {
-            throw new AccountLimitException("Cannot add more than " + _userLimit + " remote access vpn users");
-        }
-
-        VpnUser user = _vpnUsersDao.persist(new VpnUserVO(vpnOwnerId, owner.getDomainId(), username, password));
-        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_ADD, user.getAccountId(), 0, user.getId(),
-                user.getUsername(), user.getClass().getName(), user.getUuid());
-        txn.commit();
-        return user;
+        return Transaction.execute(new TransactionCallback<VpnUser>() {
+            @Override
+            public VpnUser doInTransaction(TransactionStatus status) {
+                Account owner = _accountDao.lockRow(vpnOwnerId, true);
+                if (owner == null) {
+                    throw new InvalidParameterValueException("Unable to add vpn user: Another operation active");
+                }
+                _accountMgr.checkAccess(caller, null, true, owner);
+        
+                //don't allow duplicated user names for the same account
+                VpnUserVO vpnUser = _vpnUsersDao.findByAccountAndUsername(owner.getId(), username);
+                if (vpnUser != null) {
+                    throw new InvalidParameterValueException("VPN User with name " + username + " is already added for account " + owner);
+                }
+        
+                long userCount = _vpnUsersDao.getVpnUserCount(owner.getId());
+                if (userCount >= _userLimit) {
+                    throw new AccountLimitException("Cannot add more than " + _userLimit + " remote access vpn users");
+                }
+        
+                VpnUser user = _vpnUsersDao.persist(new VpnUserVO(vpnOwnerId, owner.getDomainId(), username, password));
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_ADD, user.getAccountId(), 0, user.getId(),
+                        user.getUsername(), user.getClass().getName(), user.getUuid());
+                
+                return user;
+            }
+        });
     }
 
     @DB @Override
     public boolean removeVpnUser(long vpnOwnerId, String username, Account caller) {
-        VpnUserVO user = _vpnUsersDao.findByAccountAndUsername(vpnOwnerId, username);
+        final VpnUserVO user = _vpnUsersDao.findByAccountAndUsername(vpnOwnerId, username);
         if (user == null) {
             throw new InvalidParameterValueException("Could not find vpn user " + username);
         }
         _accountMgr.checkAccess(caller, null, true, user);
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        user.setState(State.Revoke);
-        _vpnUsersDao.update(user.getId(), user);
-        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), 0, user.getId(),
-                user.getUsername(), user.getClass().getName(), user.getUuid());
-        txn.commit();
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                user.setState(State.Revoke);
+                _vpnUsersDao.update(user.getId(), user);
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), 0, user.getId(),
+                        user.getUsername(), user.getClass().getName(), user.getUuid());
+            }
+        });
+
         return true;
     }
 
@@ -379,7 +391,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc
     public RemoteAccessVpnVO startRemoteAccessVpn(long ipAddressId, boolean openFirewall) throws ResourceUnavailableException {
         Account caller = CallContext.current().getCallingAccount();
 
-        RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByPublicIpAddress(ipAddressId);
+        final RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByPublicIpAddress(ipAddressId);
         if (vpn == null) {
             throw new InvalidParameterValueException("Unable to find your vpn: " + ipAddressId);
         }
@@ -407,20 +419,22 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc
             return vpn;
         } finally {
             if (started) {
-                Transaction txn = Transaction.currentTxn();
-                txn.start();
-                vpn.setState(RemoteAccessVpn.State.Running);
-                _remoteAccessVpnDao.update(vpn.getId(), vpn);
-
-                // Start billing of existing VPN users in ADD and Active state
-                List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId());
-                for(VpnUserVO user : vpnUsers){
-                    if(user.getState() != VpnUser.State.Revoke){
-                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_ADD, user.getAccountId(), 0,
-                                user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid());
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        vpn.setState(RemoteAccessVpn.State.Running);
+                        _remoteAccessVpnDao.update(vpn.getId(), vpn);
+        
+                        // Start billing of existing VPN users in ADD and Active state
+                        List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId());
+                        for(VpnUserVO user : vpnUsers){
+                            if(user.getState() != VpnUser.State.Revoke){
+                                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_ADD, user.getAccountId(), 0,
+                                        user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid());
+                            }
+                        }
                     }
-                }
-                txn.commit();
+                });
             }
         }
     }
@@ -479,7 +493,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc
         }
 
         for (int i = 0; i < finals.length; i++) {
-            VpnUserVO user = users.get(i);
+            final VpnUserVO user = users.get(i);
             if (finals[i]) {
                 if (user.getState() == State.Add) {
                     user.setState(State.Active);
@@ -489,12 +503,14 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc
                 }
             } else {
                 if (user.getState() == State.Add && (user.getUsername()).equals(userName)) {
-                    Transaction txn = Transaction.currentTxn();
-                    txn.start();
-                    _vpnUsersDao.remove(user.getId());
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(),
-                            0, user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid());
-                    txn.commit();
+                    Transaction.execute(new TransactionCallbackNoReturn() {
+                        @Override
+                        public void doInTransactionWithoutResult(TransactionStatus status) {
+                            _vpnUsersDao.remove(user.getId());
+                            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(),
+                                    0, user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid());
+                        }
+                    });
                 }
                 s_logger.warn("Failed to apply vpn for user " + user.getUsername() + ", accountId=" + user.getAccountId());
             }