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

[30/47] New Transaction API

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java
----------------------------------------------------------------------
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java
index 56d405e..35968ee 100644
--- a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java
+++ b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java
@@ -44,7 +44,6 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.framework.config.ConfigDepot;
 import org.apache.cloudstack.framework.config.ConfigKey;
 import org.apache.cloudstack.framework.config.Configurable;
@@ -62,6 +61,9 @@ import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.ConnectionConcierge;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.events.SubscriptionMgr;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.exception.ExceptionUtil;
@@ -532,7 +534,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C
         return new ManagedContextRunnable() {
             @Override
             protected void runInContext() {
-                Transaction txn = Transaction.open("ClusterHeartbeat");
+                TransactionLegacy txn = TransactionLegacy.open("ClusterHeartbeat");
                 try {
                     Profiler profiler = new Profiler();
                     Profiler profilerHeartbeatUpdate = new Profiler();
@@ -599,7 +601,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C
 
                     invalidHeartbeatConnection();
                 } finally {
-                    txn.transitToAutoManagedConnection(Transaction.CLOUD_DB);
+                    txn.transitToAutoManagedConnection(TransactionLegacy.CLOUD_DB);
                     txn.close("ClusterHeartbeat");
                 }
             }
@@ -620,7 +622,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C
 
     private Connection getHeartbeatConnection() throws SQLException {
         if(_heartbeatConnection == null) {
-            Connection conn = Transaction.getStandaloneConnectionWithException();
+            Connection conn = TransactionLegacy.getStandaloneConnectionWithException();
             _heartbeatConnection = new ConnectionConcierge("ClusterManagerHeartbeat", conn, false);
         }
 
@@ -629,9 +631,9 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C
 
     private void invalidHeartbeatConnection() {
         if(_heartbeatConnection != null) {
-            Connection conn = Transaction.getStandaloneConnection();
+            Connection conn = TransactionLegacy.getStandaloneConnection();
             if (conn != null) {
-                _heartbeatConnection.reset(Transaction.getStandaloneConnection());
+                _heartbeatConnection.reset(TransactionLegacy.getStandaloneConnection());
             }
         }
     }
@@ -942,58 +944,54 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C
             s_logger.info("Starting cluster manager, msid : " + _msId);
         }
 
-        Transaction txn = Transaction.currentTxn();
-        try {
-            txn.start();
-
-            final Class<?> c = this.getClass();
-            String version = c.getPackage().getImplementationVersion();
+        ManagementServerHostVO mshost = Transaction.execute(new TransactionCallback<ManagementServerHostVO>() {
+            @Override
+            public ManagementServerHostVO doInTransaction(TransactionStatus status) {
 
-            ManagementServerHostVO mshost = _mshostDao.findByMsid(_msId);
-            if (mshost == null) {
-                mshost = new ManagementServerHostVO();
-                mshost.setMsid(_msId);
-                mshost.setRunid(getCurrentRunId());
-                mshost.setName(NetUtils.getHostName());
-                mshost.setVersion(version);
-                mshost.setServiceIP(_clusterNodeIP);
-                mshost.setServicePort(_currentServiceAdapter.getServicePort());
-                mshost.setLastUpdateTime(DateUtil.currentGMTTime());
-                mshost.setRemoved(null);
-                mshost.setAlertCount(0);
-                mshost.setState(ManagementServerHost.State.Up);
-                _mshostDao.persist(mshost);
-
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("New instance of management server msid " + _msId + " is being started");
-                }
-            } else {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("Management server " + _msId + " is being started");
+                final Class<?> c = this.getClass();
+                String version = c.getPackage().getImplementationVersion();
+    
+                ManagementServerHostVO mshost = _mshostDao.findByMsid(_msId);
+                if (mshost == null) {
+                    mshost = new ManagementServerHostVO();
+                    mshost.setMsid(_msId);
+                    mshost.setRunid(getCurrentRunId());
+                    mshost.setName(NetUtils.getHostName());
+                    mshost.setVersion(version);
+                    mshost.setServiceIP(_clusterNodeIP);
+                    mshost.setServicePort(_currentServiceAdapter.getServicePort());
+                    mshost.setLastUpdateTime(DateUtil.currentGMTTime());
+                    mshost.setRemoved(null);
+                    mshost.setAlertCount(0);
+                    mshost.setState(ManagementServerHost.State.Up);
+                    _mshostDao.persist(mshost);
+    
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("New instance of management server msid " + _msId + " is being started");
+                    }
+                } else {
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Management server " + _msId + " is being started");
+                    }
+    
+                    _mshostDao.update(mshost.getId(), getCurrentRunId(), NetUtils.getHostName(), version, _clusterNodeIP, _currentServiceAdapter.getServicePort(), DateUtil.currentGMTTime());
                 }
-
-                _mshostDao.update(mshost.getId(), getCurrentRunId(), NetUtils.getHostName(), version, _clusterNodeIP, _currentServiceAdapter.getServicePort(), DateUtil.currentGMTTime());
+                
+                return mshost;
             }
+        });
 
-            txn.commit();
-
-            _mshostId = mshost.getId();
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Management server (host id : " + _mshostId + ") is being started at " + _clusterNodeIP + ":" + _currentServiceAdapter.getServicePort());
-            }
-            
-            _mshostPeerDao.clearPeerInfo(_mshostId);
-
-            // use seperate thread for heartbeat updates
-            _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HeartbeatInterval.value(), HeartbeatInterval.value(), TimeUnit.MILLISECONDS);
-            _notificationExecutor.submit(getNotificationTask());
+        _mshostId = mshost.getId();
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Management server (host id : " + _mshostId + ") is being started at " + _clusterNodeIP + ":" + _currentServiceAdapter.getServicePort());
+        }
+        
+        _mshostPeerDao.clearPeerInfo(_mshostId);
 
-        } catch (Throwable e) {
-            s_logger.error("Unexpected exception : ", e);
-            txn.rollback();
+        // use seperate thread for heartbeat updates
+        _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HeartbeatInterval.value(), HeartbeatInterval.value(), TimeUnit.MILLISECONDS);
+        _notificationExecutor.submit(getNotificationTask());
 
-            throw new CloudRuntimeException("Unable to initialize cluster info into database");
-        }
 
         if (s_logger.isInfoEnabled()) {
             s_logger.info("Cluster manager was started successfully");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java
----------------------------------------------------------------------
diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java
index 879c4ce..246bfe6 100644
--- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java
+++ b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java
@@ -38,7 +38,7 @@ import com.cloud.utils.db.Filter;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionLegacy;
 import com.cloud.utils.exception.CloudRuntimeException;
 
 @Local(value={ManagementServerHostDao.class})
@@ -52,7 +52,7 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServer
 
 	@Override
     public void invalidateRunSession(long id, long runid) {
-	    Transaction txn = Transaction.currentTxn();
+	    TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         try {
             pstmt = txn.prepareAutoCloseStatement("update mshost set runid=0, state='Down' where id=? and runid=?");
@@ -81,7 +81,7 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServer
 	@Override
     @DB
 	public void update(long id, long runid, String name, String version, String serviceIP, int servicePort, Date lastUpdate) {
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         try {
             txn.start();
@@ -106,7 +106,7 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServer
 	@Override
     @DB
     public boolean remove(Long id) {
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
     
         try {
         	txn.start();
@@ -127,7 +127,7 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServer
 	@Override
     @DB
 	public void update(long id, long runid, Date lastUpdate) {
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         try {
             txn.start();
@@ -167,7 +167,7 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServer
 	@Override
     @DB
 	public int increaseAlertCount(long id) {
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         int changedRows = 0;
         try {
@@ -209,7 +209,7 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServer
 	
 	@Override
     public void update(long id, long runId, State state, Date lastUpdate) {
-	    Transaction txn = Transaction.currentTxn();
+	    TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         try {
             pstmt = txn.prepareAutoCloseStatement("update mshost set state=?, last_update=? where id=? and runid=?");
@@ -241,7 +241,7 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServer
 	public List<Long> listOrphanMsids() {
 		List<Long> orphanList = new ArrayList<Long>();
 		
-	    Transaction txn = Transaction.currentTxn();
+	    TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         try {
             pstmt = txn.prepareAutoCloseStatement(

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java
----------------------------------------------------------------------
diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java
index 8ef2e82..f51076c 100644
--- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java
+++ b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java
@@ -28,7 +28,7 @@ import com.cloud.utils.db.DB;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionLegacy;
 
 @Local(value={ManagementServerHostPeerDao.class})
 public class ManagementServerHostPeerDaoImpl extends GenericDaoBase<ManagementServerHostPeerVO, Long> implements ManagementServerHostPeerDao {
@@ -68,7 +68,7 @@ public class ManagementServerHostPeerDaoImpl extends GenericDaoBase<ManagementSe
     @Override
     @DB
     public void updatePeerInfo(long ownerMshost, long peerMshost, long peerRunid, ManagementServerHost.State peerState) {
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
         try {
             txn.start();
         

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java
----------------------------------------------------------------------
diff --git a/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java b/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java
index e402988..1f649d4 100644
--- a/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java
+++ b/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java
@@ -34,7 +34,7 @@ import com.cloud.utils.db.DB;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionLegacy;
 import com.cloud.utils.exception.CloudRuntimeException;
 
 @Component
@@ -132,7 +132,7 @@ public class ConfigurationDaoImpl extends GenericDaoBase<ConfigurationVO, String
     @Override
     @Deprecated
     public boolean update(String name, String value) {
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
         try {
             PreparedStatement stmt = txn.prepareStatement(UPDATE_CONFIGURATION_SQL);
             stmt.setString(1, value);
@@ -147,7 +147,7 @@ public class ConfigurationDaoImpl extends GenericDaoBase<ConfigurationVO, String
 
     @Override
     public boolean update(String name, String category, String value) {
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
         try {
             value = ("Hidden".equals(category) || "Secure".equals(category)) ? DBEncryptionUtil.encrypt(value) : value;
             PreparedStatement stmt = txn.prepareStatement(UPDATE_CONFIGURATION_SQL);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java b/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
index 9b13eb8..b7246a9 100755
--- a/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
+++ b/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
@@ -39,6 +39,7 @@ import org.jasypt.properties.EncryptableProperties;
 
 import com.cloud.utils.PropertiesUtil;
 import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionLegacy;
 import com.cloud.utils.exception.CloudRuntimeException;
 
 import org.apache.commons.configuration.ConfigurationException;
@@ -227,7 +228,7 @@ public class EncryptionSecretKeyChanger {
 		initEncryptor(newEncryptor, newDBKey);
 		System.out.println("Initialised Encryptors");
 		
-		Transaction txn = Transaction.open("Migrate");
+		TransactionLegacy txn = TransactionLegacy.open("Migrate");
 		txn.start();
 		try {
 			Connection conn;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java b/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java
index c3c24f9..acb9cc6 100644
--- a/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java
+++ b/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java
@@ -178,7 +178,7 @@ public class ConnectionConcierge {
                 return "Not Found";
             }
 
-            Connection conn = Transaction.getStandaloneConnection();
+            Connection conn = TransactionLegacy.getStandaloneConnection();
             if (conn == null) {
                 return "Unable to get anotehr db connection";
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/db/src/com/cloud/utils/db/DbUtil.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/DbUtil.java b/framework/db/src/com/cloud/utils/db/DbUtil.java
index da0efbb..2570093 100755
--- a/framework/db/src/com/cloud/utils/db/DbUtil.java
+++ b/framework/db/src/com/cloud/utils/db/DbUtil.java
@@ -56,7 +56,7 @@ public class DbUtil {
     				assert(false);
     			}
     			
-    			Connection connection = Transaction.getStandaloneConnection();
+    			Connection connection = TransactionLegacy.getStandaloneConnection();
     			if(connection != null) {
     				try {
 						connection.setAutoCommit(true);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/db/src/com/cloud/utils/db/GenericDaoBase.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java
index 574974e..ba5200e 100755
--- a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java
+++ b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java
@@ -380,7 +380,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
         List<Object> groupByValues = addGroupBy(str, sc);
         addFilter(str, filter);
 
-        final Transaction txn = Transaction.currentTxn();
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
         if (lock != null) {
             assert (txn.dbTxnStarted() == true) : "As nice as I can here now....how do you lock when there's no DB transaction?  Review your db 101 course from college.";
             str.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE);
@@ -452,7 +452,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
 
         final String sql = str.toString();
 
-        final Transaction txn = Transaction.currentTxn();
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         try {
             pstmt = txn.prepareAutoCloseStatement(sql);
@@ -770,7 +770,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
         }
         SearchCriteria<T> sc = createSearchCriteria();
         sc.addAnd(_idAttributes.get(_table)[0], SearchCriteria.Op.EQ, id);
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
         txn.start();
 
         try {
@@ -791,7 +791,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
     public int update(UpdateBuilder ub, final SearchCriteria<?> sc, Integer rows) {
         StringBuilder sql = null;
         PreparedStatement pstmt = null;
-        final Transaction txn = Transaction.currentTxn();
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
         try {
             final String searchClause = sc.getWhereClause();
 
@@ -971,7 +971,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
         if (lock != null) {
             sql.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE);
         }
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         try {
             pstmt = txn.prepareAutoCloseStatement(sql.toString());
@@ -994,7 +994,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
 
     @Override
     public T acquireInLockTable(final ID id, int seconds) {
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
         T t = null;
         boolean locked  = false;
         try {
@@ -1014,7 +1014,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
 
     @Override
     public boolean releaseFromLockTable(final ID id) {
-        final Transaction txn = Transaction.currentTxn();
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
         return txn.release(_table + id);
     }
 
@@ -1025,13 +1025,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
 
     @Override
     public boolean lockInLockTable(final String id, int seconds) {
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
         return txn.lock(_table + id, seconds);
     }
 
     @Override
     public boolean unlockFromLockTable(final String id) {
-        final Transaction txn = Transaction.currentTxn();
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
         return txn.release(_table + id);
     }
 
@@ -1076,7 +1076,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
     }
 
     protected List<T> executeList(final String sql, final Object... params) {
-        final Transaction txn = Transaction.currentTxn();
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         final List<T> result = new ArrayList<T>();
         try {
@@ -1118,7 +1118,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
 
     @Override
     public boolean expunge(final ID id) {
-        final Transaction txn = Transaction.currentTxn();
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         String sql = null;
         try {
@@ -1158,7 +1158,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
 
         final String sql = str.toString();
 
-        final Transaction txn = Transaction.currentTxn();
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         try {
             pstmt = txn.prepareAutoCloseStatement(sql);
@@ -1296,7 +1296,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
         }
 
         ID id = null;
-        final Transaction txn = Transaction.currentTxn();
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         String sql = null;
         try {
@@ -1359,7 +1359,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
     }
 
     protected void insertElementCollection(T entity, Attribute idAttribute, ID id, Map<Attribute, Object> ecAttributes) throws SQLException {
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
         txn.start();
         for (Map.Entry<Attribute, Object> entry : ecAttributes.entrySet()) {
             Attribute attr = entry.getKey();
@@ -1591,7 +1591,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
     protected void loadCollection(T entity, Attribute attr)  {
         EcInfo ec = (EcInfo)attr.attache;
 
-        Transaction txn = Transaction.currentTxn();
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
         ResultSet rs = null;
         PreparedStatement pstmt = null;
         try {
@@ -1675,7 +1675,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
         }
         final StringBuilder sql = new StringBuilder("DELETE FROM ");
         sql.append(_table).append(" WHERE ").append(_removed.first()).append(" IS NOT NULL");
-        final Transaction txn = Transaction.currentTxn();
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         try {
             txn.start();
@@ -1708,7 +1708,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
             return expunge(id);
         }
 
-        final Transaction txn = Transaction.currentTxn();
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
         PreparedStatement pstmt = null;
         try {
 
@@ -1817,7 +1817,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
 
         // we have to disable group by in getting count, since count for groupBy clause will be different.
         //List<Object> groupByValues = addGroupBy(str, sc);
-        final Transaction txn = Transaction.currentTxn();
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
         final String sql = str.toString();
 
         PreparedStatement pstmt = null;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/db/src/com/cloud/utils/db/Merovingian2.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/Merovingian2.java b/framework/db/src/com/cloud/utils/db/Merovingian2.java
index 0e0e8f2..8544aab 100644
--- a/framework/db/src/com/cloud/utils/db/Merovingian2.java
+++ b/framework/db/src/com/cloud/utils/db/Merovingian2.java
@@ -65,7 +65,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean {
         _msId = msId;
         Connection conn = null;
         try {
-            conn = Transaction.getStandaloneConnectionWithException();
+            conn = TransactionLegacy.getStandaloneConnectionWithException();
             conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
             conn.setAutoCommit(true);
             _concierge = new ConnectionConcierge("LockMaster", conn, true);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/db/src/com/cloud/utils/db/SequenceFetcher.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/SequenceFetcher.java b/framework/db/src/com/cloud/utils/db/SequenceFetcher.java
index 8823552..bb45847 100644
--- a/framework/db/src/com/cloud/utils/db/SequenceFetcher.java
+++ b/framework/db/src/com/cloud/utils/db/SequenceFetcher.java
@@ -98,7 +98,7 @@ public class SequenceFetcher {
                 sql.append(_tg.valueColumnName()).append(" FROM ").append(_tg.table());
                 sql.append(" WHERE ").append(_tg.pkColumnName()).append(" = ? FOR UPDATE");
                 
-                Transaction txn = Transaction.open("Sequence");
+                TransactionLegacy txn = TransactionLegacy.open("Sequence");
                 
                 PreparedStatement selectStmt = txn.prepareStatement(sql.toString());
                 if (_key == null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/db/src/com/cloud/utils/db/Transaction.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/Transaction.java b/framework/db/src/com/cloud/utils/db/Transaction.java
index 8c2f199..0ca1cc7 100755
--- a/framework/db/src/com/cloud/utils/db/Transaction.java
+++ b/framework/db/src/com/cloud/utils/db/Transaction.java
@@ -16,1158 +16,50 @@
 // under the License.
 package com.cloud.utils.db;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Savepoint;
-import java.sql.Statement;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
 import java.util.concurrent.atomic.AtomicLong;
 
-import javax.sql.DataSource;
+import com.cloud.utils.exception.ExceptionUtil;
 
-import org.apache.commons.dbcp.ConnectionFactory;
-import org.apache.commons.dbcp.DriverManagerConnectionFactory;
-import org.apache.commons.dbcp.PoolableConnectionFactory;
-import org.apache.commons.dbcp.PoolingDataSource;
-import org.apache.commons.pool.KeyedObjectPoolFactory;
-import org.apache.commons.pool.impl.GenericObjectPool;
-import org.apache.commons.pool.impl.StackKeyedObjectPoolFactory;
-import org.apache.log4j.Logger;
-import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
-import org.jasypt.properties.EncryptableProperties;
-
-import com.cloud.utils.Pair;
-import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.crypt.EncryptionSecretKeyChecker;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.mgmt.JmxUtil;
-
-/**
- * Transaction abstracts away the Connection object in JDBC.  It allows the
- * following things that the Connection object does not.
- * 
- *   1. Transaction can be started at an entry point and whether the DB
- *      actions should be auto-commit or not determined at that point.
- *   2. DB Connection is allocated only when it is needed.
- *   3. Code does not need to know if a transaction has been started or not.
- *      It just starts/ends a transaction and we resolve it correctly with
- *      the previous actions.
- *
- * Note that this class is not synchronous but it doesn't need to be because
- * it is stored with TLS and is one per thread.  Use appropriately.
- */
 public class Transaction {
-    private static final Logger s_logger = Logger.getLogger(Transaction.class.getName() + "." + "Transaction");
-    private static final Logger s_stmtLogger = Logger.getLogger(Transaction.class.getName() + "." + "Statement");
-    private static final Logger s_lockLogger = Logger.getLogger(Transaction.class.getName() + "." + "Lock");
-    private static final Logger s_connLogger = Logger.getLogger(Transaction.class.getName() + "." + "Connection");
-
-    private static final ThreadLocal<Transaction> tls = new ThreadLocal<Transaction>();
-    private static final String START_TXN = "start_txn";
-    private static final String CURRENT_TXN = "current_txn";
-    private static final String CREATE_TXN = "create_txn";
-    private static final String CREATE_CONN = "create_conn";
-    private static final String STATEMENT = "statement";
-    private static final String ATTACHMENT = "attachment";
+    private final static AtomicLong counter = new AtomicLong(0);
+    private final static TransactionStatus STATUS = new TransactionStatus() {
+    };
 
-    public static final short CLOUD_DB = 0;
-    public static final short USAGE_DB = 1;
-    public static final short AWSAPI_DB = 2;
-    public static final short SIMULATOR_DB = 3;
-    public static final short CONNECTED_DB = -1;
-
-    private static AtomicLong s_id = new AtomicLong();
-    private static final TransactionMBeanImpl s_mbean = new TransactionMBeanImpl();
-    static {
+    public static <T> T execute(TransactionCallback<T> callback) {
+        String name = "tx-" + counter.incrementAndGet();
+        TransactionLegacy txn = TransactionLegacy.open(name);
         try {
-            JmxUtil.registerMBean("Transaction", "Transaction", s_mbean);
-        } catch (Exception e) {
-            s_logger.error("Unable to register mbean for transaction", e);
-        }
-        
-        /* FIXME: We need a better solution for this
-         * Initialize encryption if we need it for db.properties
-         */ 
-        EncryptionSecretKeyChecker enc = new EncryptionSecretKeyChecker();
-        enc.check();  
-    }
-
-    private final LinkedList<StackElement> _stack;
-    private long _id;
-
-    private final LinkedList<Pair<String, Long>> _lockTimes = new LinkedList<Pair<String, Long>>();
-
-    private String _name;
-    private Connection _conn;
-    private boolean _txn;
-    private short _dbId;
-    private long _txnTime;
-    private Statement _stmt;
-    private String _creator;
-
-    private Transaction _prev = null;
-
-    public static Transaction currentTxn() {
-        Transaction txn = tls.get();
-        assert txn != null : "No Transaction on stack.  Did you mark the method with @DB?";
-
-        assert checkAnnotation(3, txn) : "Did you even read the guide to use Transaction...IOW...other people's code? Try method can't be private.  What about @DB? hmmm... could that be it? " + txn;
-        return txn;
-    }
-
-    public static Transaction open(final short databaseId) {
-        String name = buildName();
-        if (name == null) {
-            name = CURRENT_TXN;
-        }
-        return open(name, databaseId, true);
-    }
-
-    //
-    // Usage of this transaction setup should be limited, it will always open a new transaction context regardless of whether or not there is other
-    // transaction context in the stack. It is used in special use cases that we want to control DB connection explicitly and in the mean time utilize
-    // the existing DAO features
-    //
-    public void transitToUserManagedConnection(Connection conn) {
-        assert(_conn == null /*&& _stack.size() <= 1*/) : "Can't change to a user managed connection unless the stack is empty and the db connection is null, you may have forgotten to invoke transitToAutoManagedConnection to close out the DB connection: " + toString();
-        _conn = conn;
-        _dbId = CONNECTED_DB;
-    }
-
-    public void transitToAutoManagedConnection(short dbId) {
-        // assert(_stack.size() <= 1) : "Can't change to auto managed connection unless your stack is empty";
-        _dbId = dbId;
-        _conn = null;
-    }
-
-    public static Transaction open(final String name) {
-        return open(name, CLOUD_DB, false);
-    }
-
-    public static Transaction open(final String name, final short databaseId, final boolean forceDbChange) {
-        Transaction txn = tls.get();
-        boolean isNew = false;
-        if (txn == null) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Creating the transaction: " + name);
-            }
-            txn = new Transaction(name, false, databaseId);
-            tls.set(txn);
-            isNew = true;
-        } else if (forceDbChange) {
-            final short currentDbId = txn.getDatabaseId();
-            if (currentDbId != databaseId) {
-                // we need to end the current transaction and switch databases
-                txn.close(txn.getName());
-
-                txn = new Transaction(name, false, databaseId);
-                tls.set(txn);
-                isNew = true;
-            }
-        }
-
-        txn.takeOver(name, false);
-        if (isNew) {
-            s_mbean.addTransaction(txn);
-        }
-        return txn;
-    }
-
-    protected StackElement peekInStack(Object obj) {
-        final Iterator<StackElement> it = _stack.iterator();
-        while (it.hasNext()) {
-            StackElement next = it.next();
-            if (next.type == obj) {
-                return next;
-            }
-        }
-        return null;
-    }
-
-    public void registerLock(String sql) {
-        if (_txn && s_lockLogger.isDebugEnabled()) {
-            Pair<String, Long> time = new Pair<String, Long>(sql, System.currentTimeMillis());
-            _lockTimes.add(time);
+            txn.start();
+            T result = callback.doInTransaction(STATUS);
+            txn.commit();
+            return result;
+        } finally {
+            txn.close();
         }
     }
 
-    public boolean dbTxnStarted() {
-        return _txn;
-    }
-
-    public static Connection getStandaloneConnectionWithException() throws SQLException {
-        Connection conn = s_ds.getConnection();
-        if (s_connLogger.isTraceEnabled()) {
-            s_connLogger.trace("Retrieving a standalone connection: dbconn" + System.identityHashCode(conn));
-        }
-        return conn;
-    }
-
-    public static Connection getStandaloneConnection() {
-        try {
-            return getStandaloneConnectionWithException();
-        } catch (SQLException e) {
-            s_logger.error("Unexpected exception: ", e);
-            return null;
-        }
-    }
-
-    public static Connection getStandaloneUsageConnection() {
-        try {
-            Connection conn = s_usageDS.getConnection();
-            if (s_connLogger.isTraceEnabled()) {
-                s_connLogger.trace("Retrieving a standalone connection for usage: dbconn" + System.identityHashCode(conn));
-            }
-            return conn;
-        } catch (SQLException e) {
-            s_logger.warn("Unexpected exception: ", e);
-            return null;
-        }
-    }
-
-    public static Connection getStandaloneAwsapiConnection() {
+    public static <T,X extends Exception> T executeWithException(final TransactionCallbackWithException<T> callback, Class<X> exception) throws X {
         try {
-            Connection conn = s_awsapiDS.getConnection();
-            if (s_connLogger.isTraceEnabled()) {
-                s_connLogger.trace("Retrieving a standalone connection for usage: dbconn" + System.identityHashCode(conn));
-            }
-            return conn;
-        } catch (SQLException e) {
-            s_logger.warn("Unexpected exception: ", e);
-            return null;
-        }
-    }
-    
-    public static Connection getStandaloneSimulatorConnection() {
-    	try {
-    		Connection conn = s_simulatorDS.getConnection();
-    		if (s_connLogger.isTraceEnabled()) {
-                s_connLogger.trace("Retrieving a standalone connection for simulator: dbconn" + System.identityHashCode(conn));
-            }
-            return conn;
-        } catch (SQLException e) {
-            s_logger.warn("Unexpected exception: ", e);
-            return null;
-        }
-    }
-
-    protected void attach(TransactionAttachment value) {
-        _stack.push(new StackElement(ATTACHMENT, value));
-    }
-
-    protected TransactionAttachment detach(String name) {
-        Iterator<StackElement> it = _stack.descendingIterator();
-        while (it.hasNext()) {
-            StackElement element = it.next();
-            if (element.type == ATTACHMENT) {
-                TransactionAttachment att = (TransactionAttachment)element.ref;
-                if (name.equals(att.getName())) {
-                    it.remove();
-                    return att;
-                }
-            }
-        }
-        assert false : "Are you sure you attached this: " + name;
-        return null;
-    }
-
-    public static void attachToTxn(TransactionAttachment value) {
-        Transaction txn = tls.get();
-        assert txn != null && txn.peekInStack(CURRENT_TXN) != null: "Come on....how can we attach something to the transaction if you haven't started it?";
-
-        txn.attach(value);
-    }
-
-    public static TransactionAttachment detachFromTxn(String name) {
-        Transaction txn = tls.get();
-        assert txn != null : "No Transaction in TLS";
-        return txn.detach(name);
-    }
-
-    protected static boolean checkAnnotation(int stack, Transaction txn) {
-        final StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
-        StackElement se = txn.peekInStack(CURRENT_TXN);
-        if (se == null) {
-            return false;
-        }
-        
-        StringBuffer sb = new StringBuffer();
-        for (; stack < stacks.length; stack++) {
-            String methodName = stacks[stack].getMethodName();
-            sb.append(" ").append(methodName);
-            if (methodName.equals(se.ref)){
-                return true;
-            }
-        }
-        
-        // relax stack structure for several places that @DB required injection is not in place
-        s_logger.warn("Non-standard stack context that Transaction context is manaully placed into the calling chain. Stack chain: " + sb);
-        return true;
-    }
-
-    protected static String buildName() {
-        if (s_logger.isDebugEnabled()) {
-            final StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
-            final StringBuilder str = new StringBuilder();
-            int i = 3, j = 3;
-            while (j < 15 && i < stacks.length) {
-                StackTraceElement element = stacks[i];
-                String filename = element.getFileName();
-                String method = element.getMethodName();
-                if ((filename != null && filename.equals("<generated>")) || (method != null && method.equals("invokeSuper"))) {
-                    i++;
-                    continue;
-                }
-
-                str.append("-").append(stacks[i].getClassName().substring(stacks[i].getClassName().lastIndexOf(".") + 1)).append(".").append(stacks[i].getMethodName()).append(":").append(stacks[i].getLineNumber());
-                j++;
-                i++;
-            }
-            return str.toString();
-        }
-
-        return "";
-    }
-
-    public Transaction(final String name, final boolean forLocking, final short databaseId) {
-        _name = name;
-        _conn = null;
-        _stack = new LinkedList<StackElement>();
-        _txn = false;
-        _dbId = databaseId;
-        _id = s_id.incrementAndGet();
-        _creator = Thread.currentThread().getName();
-    }
-
-    public String getCreator() {
-        return _creator;
-    }
-
-    public long getId() {
-        return _id;
-    }
-
-    public String getName() {
-        return _name;
-    }
-
-    public Short getDatabaseId() {
-        return _dbId;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder str = new StringBuilder((_name != null ? _name : ""));
-        str.append(" : ");
-        for (final StackElement se : _stack) {
-            if (se.type == CURRENT_TXN) {
-                str.append(se.ref).append(", ");
-            }
-        }
-
-        return str.toString();
-    }
-
-    protected void mark(final String name) {
-        _stack.push(new StackElement(CURRENT_TXN, name));
-    }
-
-    public boolean lock(final String name, final int timeoutSeconds) {
-        Merovingian2 lockMaster = Merovingian2.getLockMaster();
-        if (lockMaster == null) {
-            throw new CloudRuntimeException("There's no support for locking yet");
-        }
-        return lockMaster.acquire(name, timeoutSeconds);
-    }
-
-    public boolean release(final String name) {
-        Merovingian2 lockMaster = Merovingian2.getLockMaster();
-        if (lockMaster == null) {
-            throw new CloudRuntimeException("There's no support for locking yet");
-        }
-        return lockMaster.release(name);
-    }
-
-    public void start() {
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("txn: start requested by: " + buildName());
-        }
-
-        _stack.push(new StackElement(START_TXN, null));
-
-        if (_txn) {
-            s_logger.trace("txn: has already been started.");
-            return;
-        }
-
-        _txn = true;
-
-        _txnTime = System.currentTimeMillis();
-        if (_conn != null) {
-            try {
-                s_logger.trace("txn: set auto commit to false");
-                _conn.setAutoCommit(false);
-            } catch (final SQLException e) {
-                s_logger.warn("Unable to set auto commit: ", e);
-                throw new CloudRuntimeException("Unable to set auto commit: ", e);
-            }
-        }
-    }
-
-    protected void closePreviousStatement() {
-        if (_stmt != null) {
-            try {
-                if (s_stmtLogger.isTraceEnabled()) {
-                    s_stmtLogger.trace("Closing: " + _stmt.toString());
-                }
-                try {
-                    ResultSet rs = _stmt.getResultSet();
-                    if (rs != null && _stmt.getResultSetHoldability() != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
-                        rs.close();
-                    }
-                } catch(SQLException e) {
-                    s_stmtLogger.trace("Unable to close resultset");
-                }
-                _stmt.close();
-            } catch (final SQLException e) {
-                s_stmtLogger.trace("Unable to close statement: " + _stmt.toString());
-            } finally {
-                _stmt = null;
-            }
-        }
-    }
-
-    /**
-     * Prepares an auto close statement.  The statement is closed automatically if it is
-     * retrieved with this method.
-     * 
-     * @param sql sql String
-     * @return PreparedStatement
-     * @throws SQLException if problem with JDBC layer.
-     * 
-     * @see java.sql.Connection
-     */
-    public PreparedStatement prepareAutoCloseStatement(final String sql) throws SQLException {
-        PreparedStatement stmt = prepareStatement(sql);
-        closePreviousStatement();
-        _stmt = stmt;
-        return stmt;
-    }
-
-    public PreparedStatement prepareStatement(final String sql) throws SQLException {
-        final Connection conn = getConnection();
-        final PreparedStatement pstmt = conn.prepareStatement(sql);
-        if (s_stmtLogger.isTraceEnabled()) {
-            s_stmtLogger.trace("Preparing: " + sql);
-        }
-        return pstmt;
-    }
-
-    /**
-     * Prepares an auto close statement.  The statement is closed automatically if it is
-     * retrieved with this method.
-     * 
-     * @param sql sql String
-     * @param autoGeneratedKeys keys that are generated
-     * @return PreparedStatement
-     * @throws SQLException if problem with JDBC layer.
-     * 
-     * @see java.sql.Connection
-     */
-    public PreparedStatement prepareAutoCloseStatement(final String sql, final int autoGeneratedKeys) throws SQLException {
-        final Connection conn = getConnection();
-        final PreparedStatement pstmt = conn.prepareStatement(sql, autoGeneratedKeys);
-        if (s_stmtLogger.isTraceEnabled()) {
-            s_stmtLogger.trace("Preparing: " + sql);
-        }
-        closePreviousStatement();
-        _stmt = pstmt;
-        return pstmt;
-    }
-
-    /**
-     * Prepares an auto close statement.  The statement is closed automatically if it is
-     * retrieved with this method.
-     * 
-     * @param sql sql String
-     * @param columnNames names of the columns
-     * @return PreparedStatement
-     * @throws SQLException if problem with JDBC layer.
-     * 
-     * @see java.sql.Connection
-     */
-    public PreparedStatement prepareAutoCloseStatement(final String sql, final String[] columnNames) throws SQLException {
-        final Connection conn = getConnection();
-        final PreparedStatement pstmt = conn.prepareStatement(sql, columnNames);
-        if (s_stmtLogger.isTraceEnabled()) {
-            s_stmtLogger.trace("Preparing: " + sql);
-        }
-        closePreviousStatement();
-        _stmt = pstmt;
-        return pstmt;
-    }
-
-    /**
-     * Prepares an auto close statement.  The statement is closed automatically if it is
-     * retrieved with this method.
-     * 
-     * @param sql sql String
-     * @return PreparedStatement
-     * @throws SQLException if problem with JDBC layer.
-     * 
-     * @see java.sql.Connection
-     */
-    public PreparedStatement prepareAutoCloseStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
-        final Connection conn = getConnection();
-        final PreparedStatement pstmt = conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
-        if (s_stmtLogger.isTraceEnabled()) {
-            s_stmtLogger.trace("Preparing: " + sql);
-        }
-        closePreviousStatement();
-        _stmt = pstmt;
-        return pstmt;
-    }
-
-    /**
-     * Returns the db connection.
-     * 
-     * Note: that you can call getConnection() but beaware that
-     * all prepare statements from the Connection are not garbage
-     * collected!
-     * 
-     * @return DB Connection but make sure you understand that
-     *         you are responsible for closing the PreparedStatement.
-     * @throws SQLException
-     */
-    public Connection getConnection() throws SQLException {
-        if (_conn == null) {
-            switch (_dbId) {
-            case CLOUD_DB:
-                if(s_ds != null) {
-                    _conn = s_ds.getConnection();
-                } else {
-                    s_logger.warn("A static-initialized variable becomes null, process is dying?");
-                    throw new CloudRuntimeException("Database is not initialized, process is dying?");
-                }
-                break;
-            case USAGE_DB:
-                if(s_usageDS != null) {
-                    _conn = s_usageDS.getConnection();
-                } else {
-                    s_logger.warn("A static-initialized variable becomes null, process is dying?");
-                    throw new CloudRuntimeException("Database is not initialized, process is dying?");
-                }
-                break;
-            case AWSAPI_DB:
-        	if(s_awsapiDS != null) {
-        	    _conn = s_awsapiDS.getConnection();
-        	} else {
-        	    s_logger.warn("A static-initialized variable becomes null, process is dying?");
-                throw new CloudRuntimeException("Database is not initialized, process is dying?");
-        	}
-                break;
-
-            case SIMULATOR_DB:
-                if(s_simulatorDS != null) {
-                    _conn = s_simulatorDS.getConnection();
-                } else {
-                    s_logger.warn("A static-initialized variable becomes null, process is dying?");
-                    throw new CloudRuntimeException("Database is not initialized, process is dying?");
-                }
-                break;
-            default:
-
-        	throw new CloudRuntimeException("No database selected for the transaction");
-            }
-            _conn.setAutoCommit(!_txn);
-
-            //
-            // MySQL default transaction isolation level is REPEATABLE READ,
-            // to reduce chances of DB deadlock, we will use READ COMMITED isolation level instead
-            // see http://dev.mysql.com/doc/refman/5.0/en/innodb-deadlocks.html
-            //
-            _stack.push(new StackElement(CREATE_CONN, null));
-            if (s_connLogger.isTraceEnabled()) {
-                s_connLogger.trace("Creating a DB connection with " + (_txn ? " txn: " : " no txn: ") + " for " + _dbId + ": dbconn" + System.identityHashCode(_conn) + ". Stack: " + buildName());
-            }
-        } else {
-            s_logger.trace("conn: Using existing DB connection");
-        }
-
-        return _conn;
-    }
-
-    protected boolean takeOver(final String name, final boolean create) {
-        if (_stack.size() != 0) {
-            if (!create) {
-                // If it is not a create transaction, then let's just use the current one.
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("Using current transaction: " + toString());
-                }
-                mark(name);
-                return false;
-            }
-
-            final StackElement se = _stack.getFirst();
-            if (se.type == CREATE_TXN) {
-                // This create is called inside of another create.  Which is ok?
-                // We will let that create be responsible for cleaning up.
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("Create using current transaction: " + toString());
-                }
-                mark(name);
-                return false;
-            }
-
-            s_logger.warn("Encountered a transaction that has leaked.  Cleaning up. " + toString());
-            cleanup();
-        }
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Took over the transaction: " + name);
-        }
-        _stack.push(new StackElement(create ? CREATE_TXN : CURRENT_TXN, name));
-        _name = name;
-        return true;
-    }
-
-    public void cleanup() {
-        closePreviousStatement();
-
-        removeUpTo(null, null);
-        if (_txn) {
-            rollbackTransaction();
-        }
-        _txn = false;
-        _name = null;
-
-        closeConnection();
-
-        _stack.clear();
-        Merovingian2 lockMaster = Merovingian2.getLockMaster();
-        if (lockMaster != null) {
-            lockMaster.cleanupThread();
-        }
-    }
-
-    public void close() {
-        removeUpTo(CURRENT_TXN, null);
-
-        if (_stack.size() == 0) {
-            s_logger.trace("Transaction is done");
-            cleanup();
-        }
-    }
-
-    /**
-     * close() is used by endTxn to close the connection.  This method only
-     * closes the connection if the name is the same as what's stored.
-     * 
-     * @param name
-     * @return true if this close actually closes the connection.  false if not.
-     */
-    public boolean close(final String name) {
-        if (_name == null) {    // Already cleaned up.
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Already cleaned up." + buildName());
-            }
-            return true;
-        }
-
-        if (!_name.equals(name)) {
-            close();
-            return false;
-        }
-
-        if (s_logger.isDebugEnabled() && _stack.size() > 2) {
-            s_logger.debug("Transaction is not closed properly: " + toString() + ".  Called by " + buildName());
-        }
-
-        cleanup();
-
-        s_logger.trace("All done");
-        return true;
-    }
-
-    protected boolean hasTxnInStack() {
-        return peekInStack(START_TXN) != null;
-    }
-
-    protected void clearLockTimes() {
-        if (s_lockLogger.isDebugEnabled()) {
-            for (Pair<String, Long> time : _lockTimes) {
-                s_lockLogger.trace("SQL " + time.first() + " took " + (System.currentTimeMillis() - time.second()));
-            }
-            _lockTimes.clear();
-        }
-    }
-
-    public boolean commit() {
-        if (!_txn) {
-            s_logger.warn("txn: Commit called when it is not a transaction: " + buildName());
-            return false;
-        }
-
-        Iterator<StackElement> it = _stack.iterator();
-        while (it.hasNext()) {
-            StackElement st = it.next();
-            if (st.type == START_TXN) {
-                it.remove();
-                break;
-            }
-        }
-
-        if (hasTxnInStack()) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("txn: Not committing because transaction started elsewhere: " + buildName() + " / " + toString());
-            }
-            return false;
-        }
-
-        _txn = false;
-        try {
-            if (_conn != null) {
-                _conn.commit();
-                s_logger.trace("txn: DB Changes committed. Time = " + (System.currentTimeMillis() - _txnTime));
-                clearLockTimes();
-                closeConnection();
-            }
-            return true;
-        } catch (final SQLException e) {
-            rollbackTransaction();
-            throw new CloudRuntimeException("Unable to commit or close the connection. ", e);
-        }
-    }
-
-    protected void closeConnection() {
-        closePreviousStatement();
-
-        if (_conn == null) {
-            return;
-        }
-
-        if (_txn) {
-            s_connLogger.trace("txn: Not closing DB connection because we're still in a transaction.");
-            return;
-        }
-
-        try {
-            // we should only close db connection when it is not user managed
-            if (this._dbId != CONNECTED_DB) {
-                if (s_connLogger.isTraceEnabled()) {
-                    s_connLogger.trace("Closing DB connection: dbconn" + System.identityHashCode(_conn));
-                }                                
-                _conn.close();
-                _conn = null;  
-            }
-
-        } catch (final SQLException e) {
-            s_logger.warn("Unable to close connection", e);
-        }
-    }
-
-    protected void removeUpTo(String type, Object ref) {
-        boolean rollback = false;
-        Iterator<StackElement> it = _stack.iterator();
-        while (it.hasNext()) {
-            StackElement item = it.next();
-
-            it.remove();
-
-            try {
-                if (item.type == type && (ref == null || item.ref == ref)) {
-                    break;
-                }
-
-                if (item.type == CURRENT_TXN) {
-                    if (s_logger.isTraceEnabled()) {
-                        s_logger.trace("Releasing the current txn: " + (item.ref != null ? item.ref : ""));
-                    }
-                } else if (item.type == CREATE_CONN) {
-                    closeConnection();
-                } else if (item.type == START_TXN) {
-                    if (item.ref == null) {
-                        rollback = true;
-                    } else {
-                        try {
-                            _conn.rollback((Savepoint)ref);
-                            rollback = false;
-                        } catch (final SQLException e) {
-                            s_logger.warn("Unable to rollback Txn.", e);
-                        }
-                    }
-                } else if (item.type == STATEMENT) {
+            return execute(new TransactionCallback<T>() {
+                @Override
+                public T doInTransaction(TransactionStatus status) {
                     try {
-                        if (s_stmtLogger.isTraceEnabled()) {
-                            s_stmtLogger.trace("Closing: " + ref.toString());
-                        }
-                        Statement stmt = (Statement)ref;
-                        try {
-                            ResultSet rs = stmt.getResultSet();
-                            if (rs != null) {
-                                rs.close();
-                            }
-                        } catch(SQLException e) {
-                            s_stmtLogger.trace("Unable to close resultset");
-                        }
-                        stmt.close();
-                    } catch (final SQLException e) {
-                        s_stmtLogger.trace("Unable to close statement: " + item);
-                    }
-                } else if (item.type == ATTACHMENT) {
-                    TransactionAttachment att = (TransactionAttachment)item.ref;
-                    if (s_logger.isTraceEnabled()) {
-                        s_logger.trace("Cleaning up " + att.getName());
+                        return callback.doInTransaction(status);
+                    } catch (Exception e) {
+                        ExceptionUtil.rethrowRuntime(e);
+                        throw new TransactionWrappedExeception(e);
                     }
-                    att.cleanup();
-                }
-            } catch(Exception e) {
-                s_logger.error("Unable to clean up " + item, e);
-            }
-        }
-
-        if (rollback) {
-            rollback();
-        }
-    }
-
-    protected void rollbackTransaction() {
-        closePreviousStatement();
-        if (!_txn) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Rollback called for " + _name + " when there's no transaction: " + buildName());
-            }
-            return;
-        }
-        assert (!hasTxnInStack()) : "Who's rolling back transaction when there's still txn in stack?";
-        _txn = false;
-        try {
-            if (_conn != null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Rolling back the transaction: Time = " + (System.currentTimeMillis() - _txnTime) + " Name =  " + _name + "; called by " + buildName());
-                }
-                _conn.rollback();
-            }
-            clearLockTimes();
-            closeConnection();
-        } catch(final SQLException e) {
-            s_logger.warn("Unable to rollback", e);
-        }
-    }
-
-    protected void rollbackSavepoint(Savepoint sp) {
-        try {
-            if (_conn != null) {
-                _conn.rollback(sp);
-            }
-        } catch (SQLException e) {
-            s_logger.warn("Unable to rollback to savepoint " + sp);
-        }
-
-        if (!hasTxnInStack()) {
-            _txn = false;
-            closeConnection();
-        }
-    }
-
-    public void rollback() {
-        Iterator<StackElement> it = _stack.iterator();
-        while (it.hasNext()) {
-            StackElement st = it.next();
-            if (st.type == START_TXN) {
-                if (st.ref == null) {
-                    it.remove();
-                } else  {
-                    rollback((Savepoint)st.ref);
-                    return;
                 }
-            }
-        }
-
-        rollbackTransaction();
-    }
-
-    public Savepoint setSavepoint() throws SQLException {
-        _txn = true;
-        StackElement st = new StackElement(START_TXN, null);
-        _stack.push(st);
-        final Connection conn = getConnection();
-        final Savepoint sp = conn.setSavepoint();
-        st.ref = sp;
-
-        return sp;
-    }
-
-    public Savepoint setSavepoint(final String name) throws SQLException {
-        _txn = true;
-        StackElement st = new StackElement(START_TXN, null);
-        _stack.push(st);
-        final Connection conn = getConnection();
-        final Savepoint sp = conn.setSavepoint(name);
-        st.ref = sp;
-
-        return sp;
-    }
-
-    public void releaseSavepoint(final Savepoint sp) throws SQLException {
-        removeTxn(sp);
-        if (_conn != null) {
-            _conn.releaseSavepoint(sp);
-        }
-
-        if (!hasTxnInStack()) {
-            _txn = false;
-            closeConnection();
-        }
-    }
-
-    protected boolean hasSavepointInStack(Savepoint sp) {
-        Iterator<StackElement> it = _stack.iterator();
-        while (it.hasNext()) {
-            StackElement se = it.next();
-            if (se.type == START_TXN && se.ref == sp) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    protected void removeTxn(Savepoint sp) {
-        assert hasSavepointInStack(sp) : "Removing a save point that's not in the stack";
-
-        if (!hasSavepointInStack(sp)) {
-            return;
-        }
-
-        Iterator<StackElement> it = _stack.iterator();
-        while (it.hasNext()) {
-            StackElement se = it.next();
-            if (se.type == START_TXN) {
-                it.remove();
-                if (se.ref == sp) {
-                    return;
-                }
-            }
-        }
-    }
-
-    public void rollback(final Savepoint sp) {
-        removeTxn(sp);
-
-        rollbackSavepoint(sp);
-    }
-
-    public Connection getCurrentConnection() {
-        return _conn;
-    }
-
-    public List<StackElement> getStack() {
-        return _stack;
-    }
-
-    protected Transaction() {
-        _name = null;
-        _conn = null;
-        _stack = null;
-        _txn = false;
-        _dbId = -1;
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        if (!(_conn == null && (_stack == null || _stack.size() == 0))) {
-            assert (false) : "Oh Alex oh alex...something is wrong with how we're doing this";
-            s_logger.error("Something went wrong that a transaction is orphaned before db connection is closed");
-            cleanup();
+            });
+        } catch (TransactionWrappedExeception e) {
+            ExceptionUtil.rethrowRuntime(e.getWrapped());
+            ExceptionUtil.rethrow(e.getWrapped(), exception);
+            throw e;
         }
     }
-
-    protected class StackElement {
-        public String type;
-        public Object ref;
-
-        public StackElement (String type, Object ref) {
-            this.type = type;
-            this.ref = ref;
-        }
-
-        @Override
-        public String toString() {
-            return type + "-" + ref;
-        }
-    }
-
-    private static DataSource s_ds;
-    private static DataSource s_usageDS;
-    private static DataSource s_awsapiDS;
-    private static DataSource s_simulatorDS;
-
-    static {
-        // Initialize with assumed db.properties file
-        initDataSource("db.properties");
-    }
-
-    public static void initDataSource(String propsFileName) {
-        try {
-            File dbPropsFile = PropertiesUtil.findConfigFile(propsFileName);
-            final Properties dbProps;
-            if (EncryptionSecretKeyChecker.useEncryption()) {
-                StandardPBEStringEncryptor encryptor = EncryptionSecretKeyChecker.getEncryptor();
-                dbProps = new EncryptableProperties(encryptor);
-            } else {
-                dbProps = new Properties();
-            }
-            try {
-                dbProps.load(new FileInputStream(dbPropsFile));
-            } catch (IOException e) {
-                s_logger.fatal("Unable to load db properties file, pl. check the classpath and file path configuration", e);
-                return;
-            } catch (NullPointerException e) {
-                s_logger.fatal("Unable to locate db properties file within classpath or absolute path: " + propsFileName);
-                return;
-            }
-
-            // FIXME:  If params are missing...default them????
-            final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
-            final int cloudMaxIdle = Integer.parseInt(dbProps.getProperty("db.cloud.maxIdle"));
-            final long cloudMaxWait = Long.parseLong(dbProps.getProperty("db.cloud.maxWait"));
-            final String cloudUsername = dbProps.getProperty("db.cloud.username");
-            final String cloudPassword = dbProps.getProperty("db.cloud.password");
-            final String cloudHost = dbProps.getProperty("db.cloud.host");
-            final int cloudPort = Integer.parseInt(dbProps.getProperty("db.cloud.port"));
-            final String cloudDbName = dbProps.getProperty("db.cloud.name");
-            final boolean cloudAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.cloud.autoReconnect"));
-            final String cloudValidationQuery = dbProps.getProperty("db.cloud.validationQuery");
-            final String cloudIsolationLevel = dbProps.getProperty("db.cloud.isolation.level");
-
-            int isolationLevel = Connection.TRANSACTION_READ_COMMITTED;
-            if (cloudIsolationLevel == null) {
-                isolationLevel = Connection.TRANSACTION_READ_COMMITTED;
-            } else if (cloudIsolationLevel.equalsIgnoreCase("readcommitted")) {
-                isolationLevel = Connection.TRANSACTION_READ_COMMITTED;
-            } else if (cloudIsolationLevel.equalsIgnoreCase("repeatableread")) {
-                isolationLevel = Connection.TRANSACTION_REPEATABLE_READ;
-            } else if (cloudIsolationLevel.equalsIgnoreCase("serializable")) {
-                isolationLevel = Connection.TRANSACTION_SERIALIZABLE;
-            } else if (cloudIsolationLevel.equalsIgnoreCase("readuncommitted")) {
-                isolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED;
-            } else {
-                s_logger.warn("Unknown isolation level " + cloudIsolationLevel + ".  Using read uncommitted");
-            }
-
-            final boolean cloudTestOnBorrow = Boolean.parseBoolean(dbProps.getProperty("db.cloud.testOnBorrow"));
-            final boolean cloudTestWhileIdle = Boolean.parseBoolean(dbProps.getProperty("db.cloud.testWhileIdle"));
-            final long cloudTimeBtwEvictionRunsMillis = Long.parseLong(dbProps.getProperty("db.cloud.timeBetweenEvictionRunsMillis"));
-            final long cloudMinEvcitableIdleTimeMillis = Long.parseLong(dbProps.getProperty("db.cloud.minEvictableIdleTimeMillis"));
-            final boolean cloudPoolPreparedStatements = Boolean.parseBoolean(dbProps.getProperty("db.cloud.poolPreparedStatements"));
-            final String url = dbProps.getProperty("db.cloud.url.params");
-
-            final boolean useSSL = Boolean.parseBoolean(dbProps.getProperty("db.cloud.useSSL"));
-            if (useSSL) {
-                System.setProperty("javax.net.ssl.keyStore", dbProps.getProperty("db.cloud.keyStore"));
-                System.setProperty("javax.net.ssl.keyStorePassword", dbProps.getProperty("db.cloud.keyStorePassword"));
-                System.setProperty("javax.net.ssl.trustStore", dbProps.getProperty("db.cloud.trustStore"));
-                System.setProperty("javax.net.ssl.trustStorePassword", dbProps.getProperty("db.cloud.trustStorePassword"));
-            }
-
-            final GenericObjectPool cloudConnectionPool = new GenericObjectPool(null, cloudMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
-                    cloudMaxWait, cloudMaxIdle, cloudTestOnBorrow, false, cloudTimeBtwEvictionRunsMillis, 1, cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle);
-
-            final ConnectionFactory cloudConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + cloudHost + ":" + cloudPort + "/" + cloudDbName +
-                    "?autoReconnect=" + cloudAutoReconnect + (url != null ? "&" + url : "") + (useSSL ? "&useSSL=true" : ""), cloudUsername, cloudPassword);
-
-            final KeyedObjectPoolFactory poolableObjFactory = (cloudPoolPreparedStatements ? new StackKeyedObjectPoolFactory() : null);
-
-            final PoolableConnectionFactory cloudPoolableConnectionFactory = new PoolableConnectionFactory(cloudConnectionFactory, cloudConnectionPool, poolableObjFactory,
-                    cloudValidationQuery, false, false, isolationLevel);
-
-            // Default Data Source for CloudStack
-            s_ds = new PoolingDataSource(cloudPoolableConnectionFactory.getPool());
-
-            // Configure the usage db
-            final int usageMaxActive = Integer.parseInt(dbProps.getProperty("db.usage.maxActive"));
-            final int usageMaxIdle = Integer.parseInt(dbProps.getProperty("db.usage.maxIdle"));
-            final long usageMaxWait = Long.parseLong(dbProps.getProperty("db.usage.maxWait"));
-            final String usageUsername = dbProps.getProperty("db.usage.username");
-            final String usagePassword = dbProps.getProperty("db.usage.password");
-            final String usageHost = dbProps.getProperty("db.usage.host");
-            final int usagePort = Integer.parseInt(dbProps.getProperty("db.usage.port"));
-            final String usageDbName = dbProps.getProperty("db.usage.name");
-            final boolean usageAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.usage.autoReconnect"));
-            final String usageUrl = dbProps.getProperty("db.usage.url.params");
-
-            final GenericObjectPool usageConnectionPool = new GenericObjectPool(null, usageMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
-                    usageMaxWait, usageMaxIdle);
-
-            final ConnectionFactory usageConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + usageHost + ":" + usagePort + "/" + usageDbName +
-                    "?autoReconnect=" + usageAutoReconnect + (usageUrl != null ? "&" + usageUrl : ""), usageUsername, usagePassword);
-
-            final PoolableConnectionFactory usagePoolableConnectionFactory = new PoolableConnectionFactory(usageConnectionFactory, usageConnectionPool,
-                    new StackKeyedObjectPoolFactory(), null, false, false);
-
-            // Data Source for usage server
-            s_usageDS = new PoolingDataSource(usagePoolableConnectionFactory.getPool());
-
-            // Configure awsapi db
-            final String awsapiDbName = dbProps.getProperty("db.awsapi.name");
-            final GenericObjectPool awsapiConnectionPool = new GenericObjectPool(null, usageMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
-                    usageMaxWait, usageMaxIdle);
-            final ConnectionFactory awsapiConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + cloudHost + ":" + cloudPort + "/" + awsapiDbName +
-                    "?autoReconnect=" + usageAutoReconnect, cloudUsername, cloudPassword);
-            final PoolableConnectionFactory awsapiPoolableConnectionFactory = new PoolableConnectionFactory(awsapiConnectionFactory, awsapiConnectionPool,
-                    new StackKeyedObjectPoolFactory(), null, false, false);
-
-            // Data Source for awsapi
-            s_awsapiDS = new PoolingDataSource(awsapiPoolableConnectionFactory.getPool());
-
-            try {
-                // Configure the simulator db
-                final int simulatorMaxActive = Integer.parseInt(dbProps.getProperty("db.simulator.maxActive"));
-                final int simulatorMaxIdle = Integer.parseInt(dbProps.getProperty("db.simulator.maxIdle"));
-                final long simulatorMaxWait = Long.parseLong(dbProps.getProperty("db.simulator.maxWait"));
-                final String simulatorUsername = dbProps.getProperty("db.simulator.username");
-                final String simulatorPassword = dbProps.getProperty("db.simulator.password");
-                final String simulatorHost = dbProps.getProperty("db.simulator.host");
-                final int simulatorPort = Integer.parseInt(dbProps.getProperty("db.simulator.port"));
-                final String simulatorDbName = dbProps.getProperty("db.simulator.name");
-                final boolean simulatorAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.simulator.autoReconnect"));
-
-                final GenericObjectPool simulatorConnectionPool = new GenericObjectPool(null, simulatorMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
-                        simulatorMaxWait, simulatorMaxIdle);
-
-                final ConnectionFactory simulatorConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + simulatorHost + ":" + simulatorPort + "/" + simulatorDbName +
-                        "?autoReconnect=" + simulatorAutoReconnect, simulatorUsername, simulatorPassword);
-
-                final PoolableConnectionFactory simulatorPoolableConnectionFactory = new PoolableConnectionFactory(simulatorConnectionFactory, simulatorConnectionPool,
-                        new StackKeyedObjectPoolFactory(), null, false, false);
-                s_simulatorDS = new PoolingDataSource(simulatorPoolableConnectionFactory.getPool());
-            } catch (Exception e) {
-                s_logger.debug("Simulator DB properties are not available. Not initializing simulator DS");
-            }
-        } catch (final Exception e) {
-            s_ds = getDefaultDataSource("cloud");
-            s_usageDS = getDefaultDataSource("cloud_usage");
-            s_simulatorDS = getDefaultDataSource("cloud_simulator");
-            s_logger.warn("Unable to load db configuration, using defaults with 5 connections. Falling back on assumed datasource on localhost:3306 using username:password=cloud:cloud. Please check your configuration", e);
-        }
-    }
-
-    private static DataSource getDefaultDataSource(final String database) {
-        final GenericObjectPool connectionPool = new GenericObjectPool(null, 5);
-        final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
-           "jdbc:mysql://localhost:3306/" + database, "cloud", "cloud");
-        final PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(
-           connectionFactory, connectionPool, null, null, false, true);
-        return new PoolingDataSource(
-           /* connectionPool */poolableConnectionFactory.getPool());
+    
+    public static Object startTransaction() {
+    	return null;
     }
     
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/db/src/com/cloud/utils/db/TransactionCallback.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/TransactionCallback.java b/framework/db/src/com/cloud/utils/db/TransactionCallback.java
new file mode 100644
index 0000000..2f68a93
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/TransactionCallback.java
@@ -0,0 +1,7 @@
+package com.cloud.utils.db;
+
+public interface TransactionCallback<T> {
+
+	public T doInTransaction(TransactionStatus status);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/db/src/com/cloud/utils/db/TransactionCallbackNoReturn.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/TransactionCallbackNoReturn.java b/framework/db/src/com/cloud/utils/db/TransactionCallbackNoReturn.java
new file mode 100644
index 0000000..7341b4d
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/TransactionCallbackNoReturn.java
@@ -0,0 +1,13 @@
+package com.cloud.utils.db;
+
+public abstract class TransactionCallbackNoReturn implements TransactionCallback<Object> {
+
+	@Override
+	public Object doInTransaction(TransactionStatus status) {
+		doInTransaction(status);
+		return null;
+	}
+
+	public abstract void doInTransactionWithoutResult(TransactionStatus status);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/db/src/com/cloud/utils/db/TransactionCallbackWithException.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/TransactionCallbackWithException.java b/framework/db/src/com/cloud/utils/db/TransactionCallbackWithException.java
new file mode 100644
index 0000000..cbf3fbd
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/TransactionCallbackWithException.java
@@ -0,0 +1,7 @@
+package com.cloud.utils.db;
+
+public interface TransactionCallbackWithException<T> {
+
+	public T doInTransaction(TransactionStatus status) throws Exception;
+	
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java b/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java
index 40fcbbf..d60ab7b 100644
--- a/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java
+++ b/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java
@@ -46,19 +46,19 @@ public class TransactionContextBuilder implements ComponentMethodInterceptor {
 
 	@Override
     public Object interceptStart(Method method, Object target) {
-    	return Transaction.open(method.getName());
+    	return TransactionLegacy.open(method.getName());
     }
     
 	@Override
     public void interceptComplete(Method method, Object target, Object objReturnedInInterceptStart) {
-    	Transaction txn = (Transaction)objReturnedInInterceptStart;
+    	TransactionLegacy txn = (TransactionLegacy)objReturnedInInterceptStart;
     	if(txn != null)
     		txn.close();
     }
     
 	@Override
     public void interceptException(Method method, Object target, Object objReturnedInInterceptStart) {
-    	Transaction txn = (Transaction)objReturnedInInterceptStart;
+	    TransactionLegacy txn = (TransactionLegacy)objReturnedInInterceptStart;
     	if(txn != null)
     		txn.close();
     }