You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2013/11/01 01:21:57 UTC

[46/50] [abbrv] Merge branch 'master' into rbac.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2ef4d520/server/src/com/cloud/network/IpAddressManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/network/IpAddressManagerImpl.java
index 4c49247,8619ae1..2347a6e
--- a/server/src/com/cloud/network/IpAddressManagerImpl.java
+++ b/server/src/com/cloud/network/IpAddressManagerImpl.java
@@@ -609,28 -615,30 +615,30 @@@ public class IpAddressManagerImpl exten
  
      @DB
      @Override
-     public boolean releasePortableIpAddress(long addrId) {
-         Transaction txn = Transaction.currentTxn();
-         GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange");
+     public boolean releasePortableIpAddress(final long addrId) {
+         final GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange");
  
-         txn.start();
          try {
+             return Transaction.execute(new TransactionCallback<Boolean>() {
+                 @Override
+                 public Boolean doInTransaction(TransactionStatus status) {
 -                    portableIpLock.lock(5);
 -                    IPAddressVO ip = _ipAddressDao.findById(addrId);
 +            portableIpLock.lock(5);
 +            IPAddressVO ip = _ipAddressDao.findById(addrId);
  
 -                    // unassign portable IP
 -                    PortableIpVO portableIp = _portableIpDao.findByIpAddress(ip.getAddress().addr());
 -                    _portableIpDao.unassignIpAddress(portableIp.getId());
 +            // unassign portable IP
 +            PortableIpVO portableIp = _portableIpDao.findByIpAddress(ip.getAddress().addr());
 +            _portableIpDao.unassignIpAddress(portableIp.getId());
  
 -                    // removed the provisioned vlan
 -                    VlanVO vlan = _vlanDao.findById(ip.getVlanId());
 -                    _vlanDao.remove(vlan.getId());
 +            // removed the provisioned vlan
 +            VlanVO vlan = _vlanDao.findById(ip.getVlanId());
 +            _vlanDao.remove(vlan.getId());
  
 -                    // remove the provisioned public ip address
 -                    _ipAddressDao.remove(ip.getId());
 +            // remove the provisioned public ip address
 +            _ipAddressDao.remove(ip.getId());
  
-             txn.commit();
 -                    return true;
 +            return true;
+                 }
+             });
          } finally {
              portableIpLock.releaseRef();
          }
@@@ -649,135 -657,138 +657,138 @@@
      }
  
      @DB
-     public PublicIp fetchNewPublicIp(long dcId, Long podId, List<Long> vlanDbIds, Account owner, VlanType vlanUse, Long guestNetworkId, boolean sourceNat, boolean assign,
-         String requestedIp, boolean isSystem, Long vpcId) throws InsufficientAddressCapacityException {
+     public PublicIp fetchNewPublicIp(final long dcId, final Long podId, final List<Long> vlanDbIds, final Account owner, final VlanType vlanUse, final Long guestNetworkId, final boolean sourceNat, final boolean assign,
+             final String requestedIp, final boolean isSystem, final Long vpcId) throws InsufficientAddressCapacityException {
+         IPAddressVO addr = Transaction.execute(new TransactionCallbackWithException<IPAddressVO,InsufficientAddressCapacityException>() {
+             @Override
+             public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
 -                StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in ");
 -                boolean fetchFromDedicatedRange = false;
 -                List<Long> dedicatedVlanDbIds = new ArrayList<Long>();
 -                List<Long> nonDedicatedVlanDbIds = new ArrayList<Long>();
 -
 -                SearchCriteria<IPAddressVO> sc = null;
 -                if (podId != null) {
 -                    sc = AssignIpAddressFromPodVlanSearch.create();
 -                    sc.setJoinParameters("podVlanMapSB", "podId", podId);
 -                    errorMessage.append(" pod id=" + podId);
 -                } else {
 -                    sc = AssignIpAddressSearch.create();
 -                    errorMessage.append(" zone id=" + dcId);
 -                }
 -
 -                // If owner has dedicated Public IP ranges, fetch IP from the dedicated range
 -                // Otherwise fetch IP from the system pool
 -                List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId());
 -                for (AccountVlanMapVO map : maps) {
 -                    if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
 -                        dedicatedVlanDbIds.add(map.getVlanDbId());
 -                }
 -                List<VlanVO> nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId);
 -                for (VlanVO nonDedicatedVlan : nonDedicatedVlans) {
 -                    if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId()))
 -                        nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId());
 -                }
 -                if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
 -                    fetchFromDedicatedRange = true;
 -                    sc.setParameters("vlanId", dedicatedVlanDbIds.toArray());
 -                    errorMessage.append(", vlanId id=" + dedicatedVlanDbIds.toArray());
 -                } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
 -                    sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
 -                    errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
 -                } else {
 -                    if (podId != null) {
 -                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
 -                        ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
 -                        throw ex;
 -                    }
 -                    s_logger.warn(errorMessage.toString());
 -                    InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
 -                    ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
 -                    throw ex;
 -                }
 +        StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in ");
 +        boolean fetchFromDedicatedRange = false;
 +        List<Long> dedicatedVlanDbIds = new ArrayList<Long>();
 +        List<Long> nonDedicatedVlanDbIds = new ArrayList<Long>();
 +
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
 +        SearchCriteria<IPAddressVO> sc = null;
 +        if (podId != null) {
 +            sc = AssignIpAddressFromPodVlanSearch.create();
 +            sc.setJoinParameters("podVlanMapSB", "podId", podId);
 +            errorMessage.append(" pod id=" + podId);
 +        } else {
 +            sc = AssignIpAddressSearch.create();
 +            errorMessage.append(" zone id=" + dcId);
 +        }
 +
 +        // If owner has dedicated Public IP ranges, fetch IP from the dedicated range
 +        // Otherwise fetch IP from the system pool
 +        List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId());
 +        for (AccountVlanMapVO map : maps) {
 +            if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
 +                dedicatedVlanDbIds.add(map.getVlanDbId());
 +        }
 +        List<VlanVO> nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId);
 +        for (VlanVO nonDedicatedVlan : nonDedicatedVlans) {
 +            if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId()))
 +                nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId());
 +        }
 +        if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
 +            fetchFromDedicatedRange = true;
 +            sc.setParameters("vlanId", dedicatedVlanDbIds.toArray());
 +            errorMessage.append(", vlanId id=" + dedicatedVlanDbIds.toArray());
 +        } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
 +            sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
 +            errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
 +        } else {
 +            if (podId != null) {
 +                InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
 +                ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
 +                throw ex;
 +            }
 +            s_logger.warn(errorMessage.toString());
 +            InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
 +            ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
 +            throw ex;
 +        }
  
 -                sc.setParameters("dc", dcId);
 +        sc.setParameters("dc", dcId);
  
 -                DataCenter zone = _entityMgr.findById(DataCenter.class, dcId);
 +        DataCenter zone = _entityMgr.findById(DataCenter.class, dcId);
  
 -                // for direct network take ip addresses only from the vlans belonging to the network
 -                if (vlanUse == VlanType.DirectAttached) {
 -                    sc.setJoinParameters("vlan", "networkId", guestNetworkId);
 -                    errorMessage.append(", network id=" + guestNetworkId);
 -                }
 -                sc.setJoinParameters("vlan", "type", vlanUse);
 +        // for direct network take ip addresses only from the vlans belonging to the network
 +        if (vlanUse == VlanType.DirectAttached) {
 +            sc.setJoinParameters("vlan", "networkId", guestNetworkId);
 +            errorMessage.append(", network id=" + guestNetworkId);
 +        }
 +        sc.setJoinParameters("vlan", "type", vlanUse);
  
 -                if (requestedIp != null) {
 -                    sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
 -                    errorMessage.append(": requested ip " + requestedIp + " is not available");
 -                }
 +        if (requestedIp != null) {
 +            sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
 +            errorMessage.append(": requested ip " + requestedIp + " is not available");
 +        }
  
 -                Filter filter = new Filter(IPAddressVO.class, "vlanId", true, 0l, 1l);
 +        Filter filter = new Filter(IPAddressVO.class, "vlanId", true, 0l, 1l);
  
 -                List<IPAddressVO> addrs = _ipAddressDao.lockRows(sc, filter, true);
 +        List<IPAddressVO> addrs = _ipAddressDao.lockRows(sc, filter, true);
  
 -                // If all the dedicated IPs of the owner are in use fetch an IP from the system pool
 -                if (addrs.size() == 0 && fetchFromDedicatedRange) {
 -                    // Verify if account is allowed to acquire IPs from the system
 -                    boolean useSystemIps = UseSystemPublicIps.valueIn(owner.getId());
 -                    if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
 -                        fetchFromDedicatedRange = false;
 -                        sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
 -                        errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
 -                        addrs = _ipAddressDao.lockRows(sc, filter, true);
 -                    }
 -                }
 +        // If all the dedicated IPs of the owner are in use fetch an IP from the system pool
 +        if (addrs.size() == 0 && fetchFromDedicatedRange) {
 +            // Verify if account is allowed to acquire IPs from the system
 +            boolean useSystemIps = UseSystemPublicIps.valueIn(owner.getId());
 +            if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
 +                fetchFromDedicatedRange = false;
 +                sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
 +                errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
 +                addrs = _ipAddressDao.lockRows(sc, filter, true);
 +            }
 +        }
  
 -                if (addrs.size() == 0) {
 -                    if (podId != null) {
 -                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
 -                        // for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object.
 -                        ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
 -                        throw ex;
 -                    }
 -                    s_logger.warn(errorMessage.toString());
 -                    InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
 -                    ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
 -                    throw ex;
 -                }
 +        if (addrs.size() == 0) {
 +            if (podId != null) {
 +                InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
 +                // for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object.
 +                ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
 +                throw ex;
 +            }
 +            s_logger.warn(errorMessage.toString());
 +            InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
 +            ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
 +            throw ex;
 +        }
  
 -                assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size();
 +        assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size();
  
 -                if (!fetchFromDedicatedRange) {
 -                    // Check that the maximum number of public IPs for the given accountId will not be exceeded
 -                    try {
 -                        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
 -                    } catch (ResourceAllocationException ex) {
 -                        s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner);
 -                        throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded.");
 -                    }
 -                }
 +        if (!fetchFromDedicatedRange) {
 +            // Check that the maximum number of public IPs for the given accountId will not be exceeded
 +            try {
 +                _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
 +            } catch (ResourceAllocationException ex) {
 +                s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner);
 +                throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded.");
 +            }
 +        }
  
 -                IPAddressVO addr = addrs.get(0);
 -                addr.setSourceNat(sourceNat);
 -                addr.setAllocatedTime(new Date());
 -                addr.setAllocatedInDomainId(owner.getDomainId());
 -                addr.setAllocatedToAccountId(owner.getId());
 -                addr.setSystem(isSystem);
 +        IPAddressVO addr = addrs.get(0);
 +        addr.setSourceNat(sourceNat);
 +        addr.setAllocatedTime(new Date());
 +        addr.setAllocatedInDomainId(owner.getDomainId());
 +        addr.setAllocatedToAccountId(owner.getId());
 +        addr.setSystem(isSystem);
  
 -                if (assign) {
 -                    markPublicIpAsAllocated(addr);
 -                } else {
 -                    addr.setState(IpAddress.State.Allocating);
 -                }
 -                addr.setState(assign ? IpAddress.State.Allocated : IpAddress.State.Allocating);
 +        if (assign) {
 +            markPublicIpAsAllocated(addr);
 +        } else {
 +            addr.setState(IpAddress.State.Allocating);
 +        }
 +        addr.setState(assign ? IpAddress.State.Allocated : IpAddress.State.Allocating);
  
 -                if (vlanUse != VlanType.DirectAttached) {
 -                    addr.setAssociatedWithNetworkId(guestNetworkId);
 -                    addr.setVpcId(vpcId);
 -                }
 +        if (vlanUse != VlanType.DirectAttached) {
 +            addr.setAssociatedWithNetworkId(guestNetworkId);
 +            addr.setVpcId(vpcId);
 +        }
  
 -                _ipAddressDao.update(addr.getId(), addr);
 +        _ipAddressDao.update(addr.getId(), addr);
  
-         txn.commit();
+                 return addr;
+             }
+         });
  
          if (vlanUse == VlanType.VirtualNetwork) {
              _firewallMgr.addSystemFirewallRules(addr, owner);
@@@ -792,40 -803,39 +803,39 @@@
  
          assert (addr.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) : "Unable to transition from state " + addr.getState() + " to " +
                                                                                                              IpAddress.State.Allocated;
- 
-         Transaction txn = Transaction.currentTxn();
- 
+         Transaction.execute(new TransactionCallbackNoReturn() {
+             @Override
+             public void doInTransactionWithoutResult(TransactionStatus status) {
 -                Account owner = _accountMgr.getAccount(addr.getAllocatedToAccountId());
 -
 -                addr.setState(IpAddress.State.Allocated);
 -                _ipAddressDao.update(addr.getId(), addr);
 -
 -                // Save usage event
 -                if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) {
 -                    VlanVO vlan = _vlanDao.findById(addr.getVlanId());
 -
 -                    String guestType = vlan.getVlanType().toString();
 -
 -                    if (!isIpDedicated(addr)) {
 -                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN,
 -                            owner.getId(),
 -                            addr.getDataCenterId(),
 -                            addr.getId(),
 -                            addr.getAddress().toString(),
 -                            addr.isSourceNat(),
 -                            guestType,
 -                            addr.getSystem(),
 -                            addr.getClass().getName(),
 -                            addr.getUuid());
 -                    }
 +        Account owner = _accountMgr.getAccount(addr.getAllocatedToAccountId());
 +
-         txn.start();
 +        addr.setState(IpAddress.State.Allocated);
 +        _ipAddressDao.update(addr.getId(), addr);
 +
 +        // Save usage event
 +        if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) {
 +            VlanVO vlan = _vlanDao.findById(addr.getVlanId());
 +
 +            String guestType = vlan.getVlanType().toString();
 +
 +            if (!isIpDedicated(addr)) {
 +                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN,
 +                    owner.getId(),
 +                    addr.getDataCenterId(),
 +                    addr.getId(),
 +                    addr.getAddress().toString(),
 +                    addr.isSourceNat(),
 +                    guestType,
 +                    addr.getSystem(),
 +                    addr.getClass().getName(),
 +                    addr.getUuid());
 +            }
-             // don't increment resource count for direct and dedicated ip addresses
-             if ((addr.getAssociatedWithNetworkId() != null || addr.getVpcId() != null) && !isIpDedicated(addr)) {
+ 
+                     if (updateIpResourceCount(addr)) {
 -                        _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip);
 -                    }
 -                }
 +                _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip);
 +            }
 +        }
- 
-         txn.commit();
+             }
+         });
      }
  
      private boolean isIpDedicated(IPAddressVO addr) {
@@@ -855,35 -865,38 +865,38 @@@
  
      @DB
      @Override
-     public PublicIp assignDedicateIpAddress(Account owner, Long guestNtwkId, Long vpcId, long dcId, boolean isSourceNat) throws ConcurrentOperationException,
+     public PublicIp assignDedicateIpAddress(Account owner, final Long guestNtwkId, final Long vpcId, final long dcId, final boolean isSourceNat) throws ConcurrentOperationException,
          InsufficientAddressCapacityException {
  
-         long ownerId = owner.getId();
+         final long ownerId = owner.getId();
  
          PublicIp ip = null;
-         Transaction txn = Transaction.currentTxn();
          try {
-             txn.start();
- 
-             owner = _accountDao.acquireInLockTable(ownerId);
+             ip = Transaction.execute(new TransactionCallbackWithException<PublicIp,InsufficientAddressCapacityException>() {
+                 @Override
+                 public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
+                     Account owner = _accountDao.acquireInLockTable(ownerId);
  
 -                    if (owner == null) {
 -                        // this ownerId comes from owner or type Account. See the class "AccountVO" and the annotations in that class
 -                        // to get the table name and field name that is queried to fill this ownerid.
 -                        ConcurrentOperationException ex = new ConcurrentOperationException("Unable to lock account");
 -                        throw ex;
 -                    }
 -                    if (s_logger.isDebugEnabled()) {
 -                        s_logger.debug("lock account " + ownerId + " is acquired");
 -                    }
 +            if (owner == null) {
 +                // this ownerId comes from owner or type Account. See the class "AccountVO" and the annotations in that class
 +                // to get the table name and field name that is queried to fill this ownerid.
 +                ConcurrentOperationException ex = new ConcurrentOperationException("Unable to lock account");
 +                throw ex;
 +            }
 +            if (s_logger.isDebugEnabled()) {
 +                s_logger.debug("lock account " + ownerId + " is acquired");
 +            }
  
-             ip = fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, false, null, false, vpcId);
+                     PublicIp ip = fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, false, null, false, vpcId);
 -                    IPAddressVO publicIp = ip.ip();
 +            IPAddressVO publicIp = ip.ip();
  
 -                    markPublicIpAsAllocated(publicIp);
 -                    _ipAddressDao.update(publicIp.getId(), publicIp);
 +            markPublicIpAsAllocated(publicIp);
 +            _ipAddressDao.update(publicIp.getId(), publicIp);
  
-             txn.commit();
+                     return ip;
+                 }
+             });
+ 
              return ip;
          } finally {
              if (owner != null) {
@@@ -977,13 -989,13 +989,13 @@@
  
      @DB
      @Override
-     public IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerUserId, DataCenter zone) throws ConcurrentOperationException,
+     public IpAddress allocateIp(final Account ipOwner, final boolean isSystem, Account caller, long callerUserId, final DataCenter zone) throws ConcurrentOperationException,
          ResourceAllocationException, InsufficientAddressCapacityException {
  
-         VlanType vlanType = VlanType.VirtualNetwork;
-         boolean assign = false;
+         final VlanType vlanType = VlanType.VirtualNetwork;
+         final boolean assign = false;
  
 -        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) {
 +        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
              // zone is of type DataCenter. See DataCenterVO.java.
              PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, " + "Zone is currently disabled");
              ex.addProxyObject(zone.getUuid(), "zoneId");
@@@ -1008,21 -1019,25 +1019,25 @@@
                  s_logger.debug("Associate IP address lock acquired");
              }
  
-             txn.start();
- 
-             ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null, isSystem, null);
+             ip = Transaction.execute(new TransactionCallbackWithException<PublicIp,InsufficientAddressCapacityException>() {
+                 @Override
+                 public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
+                     PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null, isSystem, null);
  
 -                    if (ip == null) {
 -                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone.getId());
 -                        ex.addProxyObject(ApiDBUtils.findZoneById(zone.getId()).getUuid());
 -                        throw ex;
 -                    }
 -                    CallContext.current().setEventDetails("Ip Id: " + ip.getId());
 -                    Ip ipAddress = ip.getAddress();
 +            if (ip == null) {
 +                InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone.getId());
 +                ex.addProxyObject(ApiDBUtils.findZoneById(zone.getId()).getUuid());
 +                throw ex;
 +            }
 +            CallContext.current().setEventDetails("Ip Id: " + ip.getId());
 +            Ip ipAddress = ip.getAddress();
  
 -                    s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId());
 +            s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId());
  
-             txn.commit();
+                     return ip;
+                 }
+             });
+ 
          } finally {
              if (accountToLock != null) {
                  if (s_logger.isDebugEnabled()) {
@@@ -1048,64 -1061,68 +1061,68 @@@
          try {
              portableIpLock.lock(5);
  
-             txn.start();
+             ipaddr = Transaction.execute(new TransactionCallbackWithException<IPAddressVO,InsufficientAddressCapacityException>() {
+                 @Override
+                 public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
+                     PortableIpVO allocatedPortableIp;
  
 -                    List<PortableIpVO> portableIpVOs = _portableIpDao.listByRegionIdAndState(1, PortableIp.State.Free);
 -                    if (portableIpVOs == null || portableIpVOs.isEmpty()) {
 -                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available portable IP addresses", Region.class, new Long(1));
 -                        throw ex;
 -                    }
 -        
 -                    // allocate first portable IP to the user
 -                    allocatedPortableIp = portableIpVOs.get(0);
 -                    allocatedPortableIp.setAllocatedTime(new Date());
 -                    allocatedPortableIp.setAllocatedToAccountId(ipOwner.getAccountId());
 -                    allocatedPortableIp.setAllocatedInDomainId(ipOwner.getDomainId());
 -                    allocatedPortableIp.setState(PortableIp.State.Allocated);
 -                    _portableIpDao.update(allocatedPortableIp.getId(), allocatedPortableIp);
 -        
 -                    // To make portable IP available as a zone level resource we need to emulate portable IP's (which are
 -                    // provisioned at region level) as public IP provisioned in a zone. user_ip_address and vlan combo give the
 -                    // identity of a public IP in zone. Create entry for portable ip in these tables.
 -        
 -                    // provision portable IP range VLAN into the zone
 -                    long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public).getId();
 -                    Network network = _networkModel.getSystemNetworkByZoneAndTrafficType(dcId, TrafficType.Public);
 -                    String range = allocatedPortableIp.getAddress() + "-" + allocatedPortableIp.getAddress();
 -                    VlanVO vlan = new VlanVO(VlanType.VirtualNetwork,
 -                        allocatedPortableIp.getVlan(),
 -                        allocatedPortableIp.getGateway(),
 -                        allocatedPortableIp.getNetmask(),
 -                        dcId,
 -                        range,
 -                        network.getId(),
 -                        physicalNetworkId,
 -                        null,
 -                        null,
 -                        null);
 -                    vlan = _vlanDao.persist(vlan);
 -
 -                    // provision the portable IP in to user_ip_address table
 +            List<PortableIpVO> portableIpVOs = _portableIpDao.listByRegionIdAndState(1, PortableIp.State.Free);
 +            if (portableIpVOs == null || portableIpVOs.isEmpty()) {
 +                InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available portable IP addresses", Region.class, new Long(1));
 +                throw ex;
 +            }
 +
 +            // allocate first portable IP to the user
 +            allocatedPortableIp = portableIpVOs.get(0);
 +            allocatedPortableIp.setAllocatedTime(new Date());
 +            allocatedPortableIp.setAllocatedToAccountId(ipOwner.getAccountId());
 +            allocatedPortableIp.setAllocatedInDomainId(ipOwner.getDomainId());
 +            allocatedPortableIp.setState(PortableIp.State.Allocated);
 +            _portableIpDao.update(allocatedPortableIp.getId(), allocatedPortableIp);
 +
 +            // To make portable IP available as a zone level resource we need to emulate portable IP's (which are
 +            // provisioned at region level) as public IP provisioned in a zone. user_ip_address and vlan combo give the
 +            // identity of a public IP in zone. Create entry for portable ip in these tables.
 +
 +            // provision portable IP range VLAN into the zone
 +            long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public).getId();
 +            Network network = _networkModel.getSystemNetworkByZoneAndTrafficType(dcId, TrafficType.Public);
 +            String range = allocatedPortableIp.getAddress() + "-" + allocatedPortableIp.getAddress();
 +            VlanVO vlan = new VlanVO(VlanType.VirtualNetwork,
 +                allocatedPortableIp.getVlan(),
 +                allocatedPortableIp.getGateway(),
 +                allocatedPortableIp.getNetmask(),
 +                dcId,
 +                range,
 +                network.getId(),
 +                physicalNetworkId,
 +                null,
 +                null,
 +                null);
 +            vlan = _vlanDao.persist(vlan);
 +
 +            // provision the portable IP in to user_ip_address table
-             ipaddr = new IPAddressVO(new Ip(allocatedPortableIp.getAddress()), dcId, networkId, vpcID, physicalNetworkId, network.getId(), vlan.getId(), true);
+                     IPAddressVO ipaddr = new IPAddressVO(new Ip(allocatedPortableIp.getAddress()), dcId, networkId, vpcID, physicalNetworkId, network.getId(), vlan.getId(), true);
 -                    ipaddr.setState(State.Allocated);
 -                    ipaddr.setAllocatedTime(new Date());
 -                    ipaddr.setAllocatedInDomainId(ipOwner.getDomainId());
 -                    ipaddr.setAllocatedToAccountId(ipOwner.getId());
 -                    ipaddr = _ipAddressDao.persist(ipaddr);
 -
 -                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_PORTABLE_IP_ASSIGN,
 -                        ipaddr.getId(),
 -                        ipaddr.getDataCenterId(),
 -                        ipaddr.getId(),
 -                        ipaddr.getAddress().toString(),
 -                        ipaddr.isSourceNat(),
 -                        null,
 -                        ipaddr.getSystem(),
 -                        ipaddr.getClass().getName(),
 -                        ipaddr.getUuid());
 +            ipaddr.setState(State.Allocated);
 +            ipaddr.setAllocatedTime(new Date());
 +            ipaddr.setAllocatedInDomainId(ipOwner.getDomainId());
 +            ipaddr.setAllocatedToAccountId(ipOwner.getId());
 +            ipaddr = _ipAddressDao.persist(ipaddr);
 +
 +            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_PORTABLE_IP_ASSIGN,
 +                ipaddr.getId(),
 +                ipaddr.getDataCenterId(),
 +                ipaddr.getId(),
 +                ipaddr.getAddress().toString(),
 +                ipaddr.isSourceNat(),
 +                null,
 +                ipaddr.getSystem(),
 +                ipaddr.getClass().getName(),
 +                ipaddr.getUuid());
  
-             txn.commit();
- 
+                     return ipaddr;
+                 }
+             });
          } finally {
              portableIpLock.unlock();
          }
@@@ -1413,39 -1439,42 +1439,42 @@@
          // If portable IP need to be transferred across the zones, then mark the entry corresponding to portable ip
          // in user_ip_address and vlan tables so as to emulate portable IP as provisioned in destination data center
          if (srcNetwork.getDataCenterId() != dstNetwork.getDataCenterId()) {
-             txn.start();
- 
+             Transaction.execute(new TransactionCallbackNoReturn() {
+                 @Override
+                 public void doInTransactionWithoutResult(TransactionStatus status) {
 -                    long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId();
 -                    long publicNetworkId = _networkModel.getSystemNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId();
 -
 -                    ip.setDataCenterId(dstNetwork.getDataCenterId());
 -                    ip.setPhysicalNetworkId(physicalNetworkId);
 -                    ip.setSourceNetworkId(publicNetworkId);
 -                    _ipAddressDao.update(ipAddrId, ip);
 -
 -                    VlanVO vlan = _vlanDao.findById(ip.getVlanId());
 -                    vlan.setPhysicalNetworkId(physicalNetworkId);
 -                    vlan.setNetworkId(publicNetworkId);
 -                    vlan.setDataCenterId(dstNetwork.getDataCenterId());
 -                    _vlanDao.update(ip.getVlanId(), vlan);
 +            long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId();
 +            long publicNetworkId = _networkModel.getSystemNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId();
 +
 +            ip.setDataCenterId(dstNetwork.getDataCenterId());
 +            ip.setPhysicalNetworkId(physicalNetworkId);
 +            ip.setSourceNetworkId(publicNetworkId);
 +            _ipAddressDao.update(ipAddrId, ip);
 +
 +            VlanVO vlan = _vlanDao.findById(ip.getVlanId());
 +            vlan.setPhysicalNetworkId(physicalNetworkId);
 +            vlan.setNetworkId(publicNetworkId);
 +            vlan.setDataCenterId(dstNetwork.getDataCenterId());
 +            _vlanDao.update(ip.getVlanId(), vlan);
- 
-             txn.commit();
+                 }
+             });
          }
  
          // associate portable IP with new network/VPC network
          associatePortableIPToGuestNetwork(ipAddrId, newNetworkId, false);
  
-         txn.start();
- 
+         Transaction.execute(new TransactionCallbackNoReturn() {
+             @Override
+             public void doInTransactionWithoutResult(TransactionStatus status) {
 -                if (dstNetwork.getVpcId() != null) {
 -                    ip.setVpcId(dstNetwork.getVpcId());
 -                } else {
 -                    ip.setVpcId(null);
 -                }
 +        if (dstNetwork.getVpcId() != null) {
 +            ip.setVpcId(dstNetwork.getVpcId());
 +        } else {
 +            ip.setVpcId(null);
 +        }
  
 -                _ipAddressDao.update(ipAddrId, ip);
 +        _ipAddressDao.update(ipAddrId, ip);
+             }
+         });
  
-         txn.commit();
  
          // trigger an action event for the transfer of portable IP across the networks, so that external entities
          // monitoring for this event can initiate the route advertisement for the availability of IP from the zoe
@@@ -1463,106 -1492,121 +1492,121 @@@
  
      @Override
      @DB
-     public boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network guestNetwork) throws InsufficientCapacityException,
+     public boolean associateIpAddressListToAccount(long userId, final long accountId, final long zoneId, final Long vlanId, final Network guestNetworkFinal) throws InsufficientCapacityException,
          ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException {
-         Account owner = _accountMgr.getActiveAccountById(accountId);
-         boolean createNetwork = false;
+         final Account owner = _accountMgr.getActiveAccountById(accountId);
  
-         if (guestNetwork != null && guestNetwork.getTrafficType() != TrafficType.Guest) {
-             throw new InvalidParameterValueException("Network " + guestNetwork + " is not of a type " + TrafficType.Guest);
+         if (guestNetworkFinal != null && guestNetworkFinal.getTrafficType() != TrafficType.Guest) {
+             throw new InvalidParameterValueException("Network " + guestNetworkFinal + " is not of a type " + TrafficType.Guest);
          }
  
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
+         Ternary<Boolean,List<NetworkOfferingVO>, Network> pair = null;
+         try {
+             pair = Transaction.execute(new TransactionCallbackWithException<Ternary<Boolean,List<NetworkOfferingVO>, Network>,Exception>() {
+                 @Override
+                 public Ternary<Boolean,List<NetworkOfferingVO>, Network> doInTransaction(TransactionStatus status) throws InsufficientCapacityException, ResourceAllocationException {
+                     boolean createNetwork = false;
+                     Network guestNetwork = guestNetworkFinal;
  
 -                    if (guestNetwork == null) {
 -                        List<? extends Network> networks = getIsolatedNetworksWithSourceNATOwnedByAccountInZone(zoneId, owner);
 -                        if (networks.size() == 0) {
 -                            createNetwork = true;
 -                        } else if (networks.size() == 1) {
 -                            guestNetwork = networks.get(0);
 -                        } else {
 -                            throw new InvalidParameterValueException("Error, more than 1 Guest Isolated Networks with SourceNAT "
 -                                                                     + "service enabled found for this account, cannot assosiate the IP range, please provide the network ID");
 -                        }
 -                    }
 -            
 -                    // create new Virtual network (Isolated with SourceNAT) for the user if it doesn't exist
 -                    List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false);
 -                    if (requiredOfferings.size() < 1) {
 -                        throw new CloudRuntimeException("Unable to find network offering with availability=" + Availability.Required +
 -                                                        " to automatically create the network as part of createVlanIpRange");
 -                    }
 -                    if (createNetwork) {
 -                        if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
 -                            long physicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType());
 -                            // Validate physical network
 -                            PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
 -                            if (physicalNetwork == null) {
 -                                throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: " + requiredOfferings.get(0).getTags());
 -                            }
 -            
 -                            s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() +
 -                                           " as a part of createVlanIpRange process");
 -                            guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(),
 -                                owner.getAccountName() + "-network",
 -                                owner.getAccountName() + "-network",
 -                                null,
 -                                null,
 -                                null,
 -                                null,
 -                                owner,
 -                                null,
 -                                physicalNetwork,
 -                                zoneId,
 -                                ACLType.Account,
 -                                null,
 -                                null,
 -                                null,
 -                                null,
 -                                true,
 -                                null);
 -                            if (guestNetwork == null) {
 -                                s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
 -                                throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT " +
 -                                                                "service enabled as a part of createVlanIpRange, for the account " + accountId + "in zone " + zoneId);
 -                            }
 -                        } else {
 -                            throw new CloudRuntimeException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled);
 -                        }
 -                    }
 -            
 -                    // Check if there is a source nat ip address for this account; if not - we have to allocate one
 -                    boolean allocateSourceNat = false;
 -                    List<IPAddressVO> sourceNat = _ipAddressDao.listByAssociatedNetwork(guestNetwork.getId(), true);
 -                    if (sourceNat.isEmpty()) {
 -                        allocateSourceNat = true;
 -                    }
 -            
 -                    // update all ips with a network id, mark them as allocated and update resourceCount/usage
 -                    List<IPAddressVO> ips = _ipAddressDao.listByVlanId(vlanId);
 -                    boolean isSourceNatAllocated = false;
 -                    for (IPAddressVO addr : ips) {
 -                        if (addr.getState() != State.Allocated) {
 -                            if (!isSourceNatAllocated && allocateSourceNat) {
 -                                addr.setSourceNat(true);
 -                                isSourceNatAllocated = true;
 -                            } else {
 -                                addr.setSourceNat(false);
 -                            }
 -                            addr.setAssociatedWithNetworkId(guestNetwork.getId());
 -                            addr.setVpcId(guestNetwork.getVpcId());
 -                            addr.setAllocatedTime(new Date());
 -                            addr.setAllocatedInDomainId(owner.getDomainId());
 -                            addr.setAllocatedToAccountId(owner.getId());
 -                            addr.setSystem(false);
 -                            addr.setState(IpAddress.State.Allocating);
 -                            markPublicIpAsAllocated(addr);
 -                        }
 -                    }
 +        if (guestNetwork == null) {
 +            List<? extends Network> networks = getIsolatedNetworksWithSourceNATOwnedByAccountInZone(zoneId, owner);
 +            if (networks.size() == 0) {
 +                createNetwork = true;
 +            } else if (networks.size() == 1) {
 +                guestNetwork = networks.get(0);
 +            } else {
 +                throw new InvalidParameterValueException("Error, more than 1 Guest Isolated Networks with SourceNAT "
 +                                                         + "service enabled found for this account, cannot assosiate the IP range, please provide the network ID");
 +            }
 +        }
 +
 +        // create new Virtual network (Isolated with SourceNAT) for the user if it doesn't exist
 +        List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false);
 +        if (requiredOfferings.size() < 1) {
 +            throw new CloudRuntimeException("Unable to find network offering with availability=" + Availability.Required +
 +                                            " to automatically create the network as part of createVlanIpRange");
 +        }
 +        if (createNetwork) {
 +            if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
 +                long physicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType());
 +                // Validate physical network
 +                PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
 +                if (physicalNetwork == null) {
 +                    throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: " + requiredOfferings.get(0).getTags());
 +                }
 +
 +                s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() +
 +                               " as a part of createVlanIpRange process");
 +                guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(),
 +                    owner.getAccountName() + "-network",
 +                    owner.getAccountName() + "-network",
 +                    null,
 +                    null,
 +                    null,
 +                    null,
 +                    owner,
 +                    null,
 +                    physicalNetwork,
 +                    zoneId,
 +                    ACLType.Account,
 +                    null,
 +                    null,
 +                    null,
 +                    null,
 +                    true,
 +                    null);
 +                if (guestNetwork == null) {
 +                    s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
 +                    throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT " +
 +                                                    "service enabled as a part of createVlanIpRange, for the account " + accountId + "in zone " + zoneId);
 +                }
 +            } else {
 +                throw new CloudRuntimeException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled);
 +            }
 +        }
 +
 +        // Check if there is a source nat ip address for this account; if not - we have to allocate one
 +        boolean allocateSourceNat = false;
 +        List<IPAddressVO> sourceNat = _ipAddressDao.listByAssociatedNetwork(guestNetwork.getId(), true);
 +        if (sourceNat.isEmpty()) {
 +            allocateSourceNat = true;
 +        }
 +
 +        // update all ips with a network id, mark them as allocated and update resourceCount/usage
 +        List<IPAddressVO> ips = _ipAddressDao.listByVlanId(vlanId);
 +        boolean isSourceNatAllocated = false;
 +        for (IPAddressVO addr : ips) {
 +            if (addr.getState() != State.Allocated) {
 +                if (!isSourceNatAllocated && allocateSourceNat) {
 +                    addr.setSourceNat(true);
 +                    isSourceNatAllocated = true;
 +                } else {
 +                    addr.setSourceNat(false);
 +                }
 +                addr.setAssociatedWithNetworkId(guestNetwork.getId());
 +                addr.setVpcId(guestNetwork.getVpcId());
 +                addr.setAllocatedTime(new Date());
 +                addr.setAllocatedInDomainId(owner.getDomainId());
 +                addr.setAllocatedToAccountId(owner.getId());
 +                addr.setSystem(false);
 +                addr.setState(IpAddress.State.Allocating);
 +                markPublicIpAsAllocated(addr);
 +            }
 +        }
+                     return new Ternary<Boolean,List<NetworkOfferingVO>, Network>(createNetwork, requiredOfferings, guestNetwork);
+                 }
+             });
+         } catch (Exception e1) {
+             ExceptionUtil.rethrowRuntime(e1);
+             ExceptionUtil.rethrow(e1, InsufficientCapacityException.class);
+             ExceptionUtil.rethrow(e1, ResourceAllocationException.class);
+             throw new IllegalStateException(e1);
+         }
  
-         txn.commit();
+         boolean createNetwork = pair.first();
+         List<NetworkOfferingVO> requiredOfferings = pair.second();
+         Network guestNetwork = pair.third();
 -        
 +
          // if the network offering has persistent set to true, implement the network
          if (createNetwork && requiredOfferings.get(0).getIsPersistent()) {
              DataCenter zone = _dcDao.findById(zoneId);
@@@ -1602,36 -1644,36 +1644,36 @@@
          }
  
          if (ip.getState() != State.Releasing) {
-             txn.start();
- 
-             // don't decrement resource count for direct and dedicated ips
-             if (ip.getAssociatedWithNetworkId() != null && !isIpDedicated(ip)) {
+             return Transaction.execute(new TransactionCallback<IPAddressVO>() {
+                 @Override
+                 public IPAddressVO doInTransaction(TransactionStatus status) {
+                     if (updateIpResourceCount(ip)) {
 -                        _resourceLimitMgr.decrementResourceCount(_ipAddressDao.findById(addrId).getAllocatedToAccountId(), ResourceType.public_ip);
 -                    }
 +                _resourceLimitMgr.decrementResourceCount(_ipAddressDao.findById(addrId).getAllocatedToAccountId(), ResourceType.public_ip);
 +            }
 +
 +            // Save usage event
 +            if (ip.getAllocatedToAccountId() != null && ip.getAllocatedToAccountId() != Account.ACCOUNT_ID_SYSTEM) {
 +                VlanVO vlan = _vlanDao.findById(ip.getVlanId());
 +
 +                String guestType = vlan.getVlanType().toString();
 +                if (!isIpDedicated(ip)) {
 +                    String eventType = ip.isPortable() ? EventTypes.EVENT_PORTABLE_IP_RELEASE : EventTypes.EVENT_NET_IP_RELEASE;
 +                    UsageEventUtils.publishUsageEvent(eventType,
 +                        ip.getAllocatedToAccountId(),
 +                        ip.getDataCenterId(),
 +                        addrId,
 +                        ip.getAddress().addr(),
 +                        ip.isSourceNat(),
 +                        guestType,
 +                        ip.getSystem(),
 +                        ip.getClass().getName(),
 +                        ip.getUuid());
 +                }
 +            }
  
-             ip = _ipAddressDao.markAsUnavailable(addrId);
- 
-             txn.commit();
 -                    // Save usage event
 -                    if (ip.getAllocatedToAccountId() != null && ip.getAllocatedToAccountId() != Account.ACCOUNT_ID_SYSTEM) {
 -                        VlanVO vlan = _vlanDao.findById(ip.getVlanId());
 -
 -                        String guestType = vlan.getVlanType().toString();
 -                        if (!isIpDedicated(ip)) {
 -                            String eventType = ip.isPortable() ? EventTypes.EVENT_PORTABLE_IP_RELEASE : EventTypes.EVENT_NET_IP_RELEASE;
 -                            UsageEventUtils.publishUsageEvent(eventType,
 -                                ip.getAllocatedToAccountId(),
 -                                ip.getDataCenterId(),
 -                                addrId,
 -                                ip.getAddress().addr(),
 -                                ip.isSourceNat(),
 -                                guestType,
 -                                ip.getSystem(),
 -                                ip.getClass().getName(),
 -                                ip.getUuid());
 -                        }
 -                    }
 -        
+                     return _ipAddressDao.markAsUnavailable(addrId);
+                 }
+             });
          }
  
          return ip;
@@@ -1811,73 -1858,73 +1858,73 @@@
  
      @Override
      @DB
-     public void allocateDirectIp(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network, String requestedIpv4, String requestedIpv6)
+     public void allocateDirectIp(final NicProfile nic, final DataCenter dc, final VirtualMachineProfile vm, final Network network, final String requestedIpv4, final String requestedIpv6)
          throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException {
+         Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientAddressCapacityException>() {
+             @Override
+             public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException {
 -                //This method allocates direct ip for the Shared network in Advance zones
 -                boolean ipv4 = false;
 -
 -                if (network.getGateway() != null) {
 -                    if (nic.getIp4Address() == null) {
 -                        ipv4 = true;
 -                        PublicIp ip = null;
 -
 -                        //Get ip address from the placeholder and don't allocate a new one
 -                        if (requestedIpv4 != null && vm.getType() == VirtualMachine.Type.DomainRouter) {
 -                            Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null);
 -                            if (placeholderNic != null) {
 -                                IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIp4Address());
 -                                ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
 -                                s_logger.debug("Nic got an ip address " + placeholderNic.getIp4Address() + " stored in placeholder nic for the network " + network);
 -                            }
 -                        }
 -
 -                        if (ip == null) {
 -                            ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false);
 -                        }
 -
 -                        nic.setIp4Address(ip.getAddress().toString());
 -                        nic.setGateway(ip.getGateway());
 -                        nic.setNetmask(ip.getNetmask());
 -                        nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
 -                        //nic.setBroadcastType(BroadcastDomainType.Vlan);
 -                        //nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
 -                        nic.setBroadcastType(network.getBroadcastDomainType());
 -                        nic.setBroadcastUri(network.getBroadcastUri());
 -                        nic.setFormat(AddressFormat.Ip4);
 -                        nic.setReservationId(String.valueOf(ip.getVlanTag()));
 -                        nic.setMacAddress(ip.getMacAddress());
 +        //This method allocates direct ip for the Shared network in Advance zones
 +        boolean ipv4 = false;
 +
-         Transaction txn = Transaction.currentTxn();
-         txn.start();
- 
 +        if (network.getGateway() != null) {
 +            if (nic.getIp4Address() == null) {
 +                ipv4 = true;
 +                PublicIp ip = null;
 +
 +                //Get ip address from the placeholder and don't allocate a new one
 +                if (requestedIpv4 != null && vm.getType() == VirtualMachine.Type.DomainRouter) {
 +                    Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null);
 +                    if (placeholderNic != null) {
 +                        IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIp4Address());
 +                        ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
 +                        s_logger.debug("Nic got an ip address " + placeholderNic.getIp4Address() + " stored in placeholder nic for the network " + network);
                      }
 -                    nic.setDns1(dc.getDns1());
 -                    nic.setDns2(dc.getDns2());
                  }
  
 -                //FIXME - get ipv6 address from the placeholder if it's stored there
 -                if (network.getIp6Gateway() != null) {
 -                    if (nic.getIp6Address() == null) {
 -                        UserIpv6Address ip = _ipv6Mgr.assignDirectIp6Address(dc.getId(), vm.getOwner(), network.getId(), requestedIpv6);
 -                        Vlan vlan = _vlanDao.findById(ip.getVlanId());
 -                        nic.setIp6Address(ip.getAddress().toString());
 -                        nic.setIp6Gateway(vlan.getIp6Gateway());
 -                        nic.setIp6Cidr(vlan.getIp6Cidr());
 -                        if (ipv4) {
 -                            nic.setFormat(AddressFormat.DualStack);
 -                        } else {
 -                            nic.setIsolationUri(IsolationType.Vlan.toUri(vlan.getVlanTag()));
 -                            nic.setBroadcastType(BroadcastDomainType.Vlan);
 -                            nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlan.getVlanTag()));
 -                            nic.setFormat(AddressFormat.Ip6);
 -                            nic.setReservationId(String.valueOf(vlan.getVlanTag()));
 -                            nic.setMacAddress(ip.getMacAddress());
 -                        }
 -                    }
 -                    nic.setIp6Dns1(dc.getIp6Dns1());
 -                    nic.setIp6Dns2(dc.getIp6Dns2());
 +                if (ip == null) {
 +                    ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false);
                  }
 +
 +                nic.setIp4Address(ip.getAddress().toString());
 +                nic.setGateway(ip.getGateway());
 +                nic.setNetmask(ip.getNetmask());
 +                nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
 +                //nic.setBroadcastType(BroadcastDomainType.Vlan);
 +                //nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
 +                nic.setBroadcastType(network.getBroadcastDomainType());
 +                nic.setBroadcastUri(network.getBroadcastUri());
 +                nic.setFormat(AddressFormat.Ip4);
 +                nic.setReservationId(String.valueOf(ip.getVlanTag()));
 +                nic.setMacAddress(ip.getMacAddress());
 +            }
 +            nic.setDns1(dc.getDns1());
 +            nic.setDns2(dc.getDns2());
 +        }
 +
 +        //FIXME - get ipv6 address from the placeholder if it's stored there
 +        if (network.getIp6Gateway() != null) {
 +            if (nic.getIp6Address() == null) {
 +                UserIpv6Address ip = _ipv6Mgr.assignDirectIp6Address(dc.getId(), vm.getOwner(), network.getId(), requestedIpv6);
 +                Vlan vlan = _vlanDao.findById(ip.getVlanId());
 +                nic.setIp6Address(ip.getAddress().toString());
 +                nic.setIp6Gateway(vlan.getIp6Gateway());
 +                nic.setIp6Cidr(vlan.getIp6Cidr());
 +                if (ipv4) {
 +                    nic.setFormat(AddressFormat.DualStack);
 +                } else {
 +                    nic.setIsolationUri(IsolationType.Vlan.toUri(vlan.getVlanTag()));
 +                    nic.setBroadcastType(BroadcastDomainType.Vlan);
 +                    nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlan.getVlanTag()));
 +                    nic.setFormat(AddressFormat.Ip6);
 +                    nic.setReservationId(String.valueOf(vlan.getVlanTag()));
 +                    nic.setMacAddress(ip.getMacAddress());
 +                }
 +            }
 +            nic.setIp6Dns1(dc.getIp6Dns1());
 +            nic.setIp6Dns2(dc.getIp6Dns2());
 +        }
- 
-         txn.commit();
+             }
+         });
      }
  
      @Override