You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by me...@apache.org on 2018/09/04 12:58:32 UTC

[22/28] ranger git commit: RANGER-2186: Increment service-specific policy and tag versions after update transaction is committed

RANGER-2186: Increment service-specific policy and tag versions after update transaction is committed


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

Branch: refs/heads/ranger-1.1
Commit: fbcaaaf6d780d959ee5fe6b5aae6c71ba289050f
Parents: b66e98d
Author: Abhay Kulkarni <ak...@hortonworks.com>
Authored: Wed Aug 15 21:03:41 2018 -0700
Committer: Mehul Parikh <me...@apache.org>
Committed: Tue Sep 4 11:45:03 2018 +0530

----------------------------------------------------------------------
 .../plugin/store/AbstractServiceStore.java      |   2 +-
 .../org/apache/ranger/biz/ServiceDBStore.java   | 148 ++++++++----------
 ...RangerTransactionSynchronizationAdapter.java | 154 ++++++++++++++-----
 .../org/apache/ranger/db/RangerDaoManager.java  |   8 +
 .../apache/ranger/db/RangerDaoManagerBase.java  |   6 -
 .../ranger/db/XXServiceVersionInfoDao.java      |  17 +-
 .../apache/ranger/biz/TestServiceDBStore.java   |  64 ++++----
 7 files changed, 236 insertions(+), 163 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ranger/blob/fbcaaaf6/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractServiceStore.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractServiceStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractServiceStore.java
index 69ded6d..b0dd283 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractServiceStore.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractServiceStore.java
@@ -138,7 +138,7 @@ public abstract class AbstractServiceStore implements ServiceStore {
 		}
 	}
 
-	protected final long getNextVersion(Long currentVersion) {
+	public static long getNextVersion(Long currentVersion) {
 		return currentVersion == null ? 1L : currentVersion + 1;
 	}
 

http://git-wip-us.apache.org/repos/asf/ranger/blob/fbcaaaf6/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index 0773616..cb5f240 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -57,6 +57,7 @@ import org.apache.ranger.common.AppConstants;
 import org.apache.ranger.common.ContextUtil;
 import org.apache.ranger.common.MessageEnums;
 import org.apache.ranger.common.RangerCommonEnums;
+import org.apache.ranger.common.db.RangerTransactionSynchronizationAdapter;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
 import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
 import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
@@ -304,6 +305,9 @@ public class ServiceDBStore extends AbstractServiceStore {
         @Autowired
         AssetMgr assetMgr;
 
+	@Autowired
+	RangerTransactionSynchronizationAdapter transactionSynchronizationAdapter;
+
 	private static volatile boolean legacyServiceDefsInitDone = false;
 	private Boolean populateExistingBaseFields = false;
 	
@@ -2032,7 +2036,7 @@ public class ServiceDBStore extends AbstractServiceStore {
 		dataHistService.createObjectDataHistory(updPolicy, RangerDataHistService.ACTION_UPDATE);
 		
 		bizUtil.createTrxLog(trxLogList);
-		
+
 		return updPolicy;
 	}
 
@@ -2814,6 +2818,8 @@ public class ServiceDBStore extends AbstractServiceStore {
 		updatePolicyVersion(service, isTagVersionUpdateNeeded);
 	}
 
+	public enum VERSION_TYPE { POLICY_VERSION, TAG_VERSION, POLICY_AND_TAG_VERSION }
+
 	private void updatePolicyVersion(RangerService service, boolean isTagVersionUpdateNeeded) throws Exception {
 		if(service == null || service.getId() == null) {
 			return;
@@ -2830,28 +2836,14 @@ public class ServiceDBStore extends AbstractServiceStore {
 			return;
 		}
 
-		XXServiceVersionInfoDao serviceVersionInfoDao = daoMgr.getXXServiceVersionInfo();
-
-		XXServiceVersionInfo serviceVersionInfoDbObj = serviceVersionInfoDao.findByServiceId(service.getId());
-
-		if(serviceVersionInfoDbObj != null) {
-			serviceVersionInfoDbObj.setPolicyVersion(getNextVersion(serviceVersionInfoDbObj.getPolicyVersion()));
-			serviceVersionInfoDbObj.setPolicyUpdateTime(new Date());
-
-			serviceVersionInfoDao.update(serviceVersionInfoDbObj);
-
-		} else {
-			LOG.warn("updatePolicyVersion(service=" + serviceDbObj.getName() + "): serviceVersionInfo not found, creating it..");
+		Runnable commitWork = new Runnable() {
+			@Override
+			public void run() {
+				persistVersionChange(daoMgr, serviceDbObj.getId(), VERSION_TYPE.POLICY_VERSION);
+			}
+		};
 
-			serviceVersionInfoDbObj = new XXServiceVersionInfo();
-			serviceVersionInfoDbObj.setServiceId(serviceDbObj.getId());
-			serviceVersionInfoDbObj.setPolicyVersion(getNextVersion(serviceDbObj.getPolicyVersion()));
-			serviceVersionInfoDbObj.setPolicyUpdateTime(new Date());
-			serviceVersionInfoDbObj.setTagVersion(serviceDbObj.getTagVersion());
-			serviceVersionInfoDbObj.setTagUpdateTime(serviceDbObj.getTagUpdateTime());
-
-			serviceVersionInfoDao.create(serviceVersionInfoDbObj);
-		}
+		transactionSynchronizationAdapter.executeOnTransactionCommit(commitWork);
 
 		// if this is a tag service, update all services that refer to this tag service
 		// so that next policy-download from plugins will get updated tag policies
@@ -2861,37 +2853,50 @@ public class ServiceDBStore extends AbstractServiceStore {
 
 			if(CollectionUtils.isNotEmpty(referringServices)) {
 				for(XXService referringService : referringServices) {
-					serviceVersionInfoDbObj = serviceVersionInfoDao.findByServiceId(referringService.getId());
-					if (serviceVersionInfoDbObj != null) {
-
-						serviceVersionInfoDbObj.setPolicyVersion(getNextVersion(serviceVersionInfoDbObj.getPolicyVersion()));
-						serviceVersionInfoDbObj.setPolicyUpdateTime(new Date());
-
-						if (filterForServicePlugin && isTagVersionUpdateNeeded) {
-							serviceVersionInfoDbObj.setTagVersion(getNextVersion(serviceVersionInfoDbObj.getTagVersion()));
-							serviceVersionInfoDbObj.setTagUpdateTime(new Date());
-						}
-						serviceVersionInfoDao.update(serviceVersionInfoDbObj);
-					} else {
-						LOG.warn("updatePolicyVersion(service=" + referringService.getName() + "): serviceVersionInfo not found, creating it..");
-						serviceVersionInfoDbObj = new XXServiceVersionInfo();
-						serviceVersionInfoDbObj.setServiceId(referringService.getId());
-						serviceVersionInfoDbObj.setPolicyVersion(getNextVersion(referringService.getPolicyVersion()));
-						serviceVersionInfoDbObj.setPolicyUpdateTime(new Date());
-						if (filterForServicePlugin && isTagVersionUpdateNeeded) {
-							serviceVersionInfoDbObj.setTagVersion(getNextVersion(referringService.getTagVersion()));
-							serviceVersionInfoDbObj.setTagUpdateTime(new Date());
-						} else {
-							serviceVersionInfoDbObj.setTagVersion(referringService.getTagVersion());
-							serviceVersionInfoDbObj.setTagUpdateTime(referringService.getTagUpdateTime());
+					commitWork = new Runnable() {
+						@Override
+						public void run() {
+							persistVersionChange(daoMgr, referringService.getId(),
+									filterForServicePlugin && isTagVersionUpdateNeeded ? VERSION_TYPE.POLICY_AND_TAG_VERSION : VERSION_TYPE.POLICY_VERSION);
 						}
-						serviceVersionInfoDao.create(serviceVersionInfoDbObj);
-					}
+					};
+					transactionSynchronizationAdapter.executeOnTransactionCommit(commitWork);
 				}
 			}
 		}
 	}
 
+	public static void persistVersionChange(RangerDaoManager daoMgr, Long id, VERSION_TYPE versionType) {
+		XXServiceVersionInfoDao serviceVersionInfoDao = daoMgr.getXXServiceVersionInfo();
+
+		XXServiceVersionInfo serviceVersionInfoDbObj = serviceVersionInfoDao.findByServiceId(id);
+
+		if(serviceVersionInfoDbObj != null) {
+			if (versionType == VERSION_TYPE.POLICY_VERSION || versionType == VERSION_TYPE.POLICY_AND_TAG_VERSION) {
+				serviceVersionInfoDbObj.setPolicyVersion(getNextVersion(serviceVersionInfoDbObj.getPolicyVersion()));
+				serviceVersionInfoDbObj.setPolicyUpdateTime(new Date());
+			}
+			if (versionType == VERSION_TYPE.TAG_VERSION || versionType == VERSION_TYPE.POLICY_AND_TAG_VERSION) {
+
+				serviceVersionInfoDbObj.setTagVersion(getNextVersion(serviceVersionInfoDbObj.getTagVersion()));
+				serviceVersionInfoDbObj.setTagUpdateTime(new Date());
+			}
+
+			serviceVersionInfoDao.update(serviceVersionInfoDbObj);
+
+		} else {
+			XXService service = daoMgr.getXXService().getById(id);
+			serviceVersionInfoDbObj = new XXServiceVersionInfo();
+			serviceVersionInfoDbObj.setServiceId(service.getId());
+			serviceVersionInfoDbObj.setPolicyVersion(1L);
+			serviceVersionInfoDbObj.setPolicyUpdateTime(new Date());
+			serviceVersionInfoDbObj.setTagVersion(1L);
+			serviceVersionInfoDbObj.setTagUpdateTime(new Date());
+
+			serviceVersionInfoDao.create(serviceVersionInfoDbObj);
+		}
+	}
+
 	private XXPolicyItem createNewPolicyItemForPolicy(RangerPolicy policy, XXPolicy xPolicy, RangerPolicyItem policyItem, XXServiceDef xServiceDef, int itemOrder, int policyItemType) throws Exception {
 		XXPolicyItem xPolicyItem = new XXPolicyItem();
 
@@ -3308,52 +3313,31 @@ public class ServiceDBStore extends AbstractServiceStore {
 		boolean isTagServiceDef = StringUtils.equals(serviceDef.getName(), EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME);
 
 		XXServiceDao serviceDao = daoMgr.getXXService();
-		XXServiceVersionInfoDao serviceVersionInfoDao = daoMgr.getXXServiceVersionInfo();
 
 		List<XXService> services = serviceDao.findByServiceDefId(serviceDef.getId());
 
 		if(CollectionUtils.isNotEmpty(services)) {
 			for(XXService service : services) {
-				XXServiceVersionInfo serviceVersionInfo = serviceVersionInfoDao.findByServiceId(service.getId());
-				if (serviceVersionInfo != null) {
-					serviceVersionInfo.setPolicyVersion(getNextVersion(serviceVersionInfo.getPolicyVersion()));
-					serviceVersionInfo.setPolicyUpdateTime(serviceDef.getUpdateTime());
-
-					serviceVersionInfoDao.update(serviceVersionInfo);
-				} else {
-					LOG.warn("updateServicesForServiceDefUpdate(service=" + service.getName() + "): serviceVersionInfo not found, creating it..");
-					serviceVersionInfo = new XXServiceVersionInfo();
-					serviceVersionInfo.setServiceId(service.getId());
-					serviceVersionInfo.setPolicyVersion(getNextVersion(service.getPolicyVersion()));
-					serviceVersionInfo.setTagVersion(service.getTagVersion());
-					serviceVersionInfo.setPolicyUpdateTime(new Date());
-					serviceVersionInfo.setTagUpdateTime(service.getTagUpdateTime());
-
-					serviceVersionInfoDao.create(serviceVersionInfo);
-				}
+				Runnable commitWork = new Runnable() {
+					@Override
+					public void run() {
+						persistVersionChange(daoMgr, service.getId(), VERSION_TYPE.POLICY_VERSION);
+					}
+				};
+				transactionSynchronizationAdapter.executeOnTransactionCommit(commitWork);
 
 				if(isTagServiceDef) {
 					List<XXService> referrringServices = serviceDao.findByTagServiceId(service.getId());
 
 					if(CollectionUtils.isNotEmpty(referrringServices)) {
 						for(XXService referringService : referrringServices) {
-							serviceVersionInfo = serviceVersionInfoDao.findByServiceId(referringService.getId());
-							if (serviceVersionInfo != null) {
-								serviceVersionInfo.setPolicyVersion(getNextVersion(serviceVersionInfo.getPolicyVersion()));
-								serviceVersionInfo.setPolicyUpdateTime(serviceDef.getUpdateTime());
-
-								serviceVersionInfoDao.update(serviceVersionInfo);
-							} else {
-								LOG.warn("updateServicesForServiceDefUpdate(service=" + referringService.getName() + "): serviceVersionInfo not found, creating it..");
-								serviceVersionInfo = new XXServiceVersionInfo();
-								serviceVersionInfo.setServiceId(referringService.getId());
-								serviceVersionInfo.setPolicyVersion(getNextVersion(referringService.getPolicyVersion()));
-								serviceVersionInfo.setTagVersion(referringService.getTagVersion());
-								serviceVersionInfo.setPolicyUpdateTime(new Date());
-								serviceVersionInfo.setTagUpdateTime(referringService.getTagUpdateTime());
-
-								serviceVersionInfoDao.create(serviceVersionInfo);
-							}
+							commitWork = new Runnable() {
+								@Override
+								public void run() {
+									persistVersionChange(daoMgr, referringService.getId(), VERSION_TYPE.POLICY_VERSION);
+								}
+							};
+							transactionSynchronizationAdapter.executeOnTransactionCommit(commitWork);
 						}
 					}
 				}

http://git-wip-us.apache.org/repos/asf/ranger/blob/fbcaaaf6/security-admin/src/main/java/org/apache/ranger/common/db/RangerTransactionSynchronizationAdapter.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/common/db/RangerTransactionSynchronizationAdapter.java b/security-admin/src/main/java/org/apache/ranger/common/db/RangerTransactionSynchronizationAdapter.java
index 2a62fb4..536ca29 100644
--- a/security-admin/src/main/java/org/apache/ranger/common/db/RangerTransactionSynchronizationAdapter.java
+++ b/security-admin/src/main/java/org/apache/ranger/common/db/RangerTransactionSynchronizationAdapter.java
@@ -22,6 +22,7 @@ package org.apache.ranger.common.db;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -46,6 +47,7 @@ public class RangerTransactionSynchronizationAdapter extends TransactionSynchron
     private static final Log LOG = LogFactory.getLog(RangerTransactionSynchronizationAdapter.class);
 
     private static final ThreadLocal<List<Runnable>> RUNNABLES = new ThreadLocal<List<Runnable>>();
+    private static final ThreadLocal<List<Runnable>> RUNNABLES_AFTER_COMMIT = new ThreadLocal<List<Runnable>>();
 
     public void executeOnTransactionCompletion(Runnable runnable) {
         if (LOG.isDebugEnabled()) {
@@ -64,7 +66,7 @@ public class RangerTransactionSynchronizationAdapter extends TransactionSynchron
         TransactionSynchronizationAdapter
         */
 
-        if (!TransactionSynchronizationManager.isSynchronizationActive()) {
+        if (!registerSynchronization()) {
             LOG.info("Transaction synchronization is NOT ACTIVE. Executing right now runnable {" + runnable + "}");
             runnable.run();
             return;
@@ -73,9 +75,36 @@ public class RangerTransactionSynchronizationAdapter extends TransactionSynchron
         if (threadRunnables == null) {
             threadRunnables = new ArrayList<Runnable>();
             RUNNABLES.set(threadRunnables);
-            // Register a new transaction synchronization for the current thread.
-            // TransactionSynchronizationManage will call afterCompletion() when current transaction completes.
-            TransactionSynchronizationManager.registerSynchronization(this);
+        }
+        threadRunnables.add(runnable);
+    }
+
+    public void executeOnTransactionCommit(Runnable runnable) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Submitting new runnable {" + runnable + "} to run after transaction is committed");
+        }
+
+        /*
+        From TransactionSynchronizationManager documentation:
+        TransactionSynchronizationManager is a central helper that manages resources and transaction synchronizations per thread.
+        Resource management code should only register synchronizations when this manager is active,
+        which can be checked via isSynchronizationActive(); it should perform immediate resource cleanup else.
+        If transaction synchronization isn't active, there is either no current transaction,
+        or the transaction manager doesn't support transaction synchronization.
+
+        Note: Synchronization is an Interface for transaction synchronization callbacks which is implemented by
+        TransactionSynchronizationAdapter
+        */
+
+        if (!registerSynchronization()) {
+            LOG.info("Transaction synchronization is NOT ACTIVE. Executing right now runnable {" + runnable + "}");
+            runnable.run();
+            return;
+        }
+        List<Runnable> threadRunnables = RUNNABLES_AFTER_COMMIT.get();
+        if (threadRunnables == null) {
+            threadRunnables = new ArrayList<Runnable>();
+            RUNNABLES_AFTER_COMMIT.set(threadRunnables);
         }
         threadRunnables.add(runnable);
     }
@@ -83,48 +112,93 @@ public class RangerTransactionSynchronizationAdapter extends TransactionSynchron
     @Override
     public void afterCompletion(int status) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("Transaction completed with status {" + (status == STATUS_COMMITTED ? "COMMITTED" : "ROLLED_BACK") + "}");
+            LOG.debug("==> RangerTransactionSynchronizationAdapter.afterCompletion(status=" + (status == STATUS_COMMITTED ? "COMMITTED" : "ROLLED_BACK") + ")");
         }
-        /* Thread runnables are expected to be executed only when the status is STATUS_ROLLED_BACK. Currently, executeOnTransactionCompletion()
-         * is called only for those changes that are going to be rolled-back by TransactionSynchronizationManager - such
-         * as when the operation returns HttpServletResponse.SC_NOT_MODIFIED status.
-         */
-        //if (status == STATUS_ROLLED_BACK) {
-            final List<Runnable> threadRunnables = RUNNABLES.get();
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Transaction completed, executing {" + threadRunnables.size() + "} runnables");
+
+        List<Runnable> allRunnables = null;
+
+        if (status == STATUS_COMMITTED) {
+            final List<Runnable> postCommitRunnables = RUNNABLES_AFTER_COMMIT.get();
+            if (CollectionUtils.isNotEmpty(postCommitRunnables)) {
+                allRunnables = postCommitRunnables;
             }
-            if (threadRunnables != null) {
-                try {
-                    //Create new  transaction
-                    TransactionTemplate txTemplate = new TransactionTemplate(txManager);
-                    txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
-
-                    txTemplate.execute(new TransactionCallback<Object>() {
-                        public Object doInTransaction(TransactionStatus status) {
-                            for (Runnable runnable : threadRunnables) {
-                                if (LOG.isDebugEnabled()) {
-                                    LOG.debug("Executing runnable {" + runnable + "}");
-                                }
-                                try {
-                                    runnable.run();
-                                } catch (RuntimeException e) {
-                                    LOG.error("Failed to execute runnable " + runnable, e);
-                                    break;
-                                }
-                            }
+        }
 
-                            return null;
-                        }
-                    });
-                } catch (Exception e) {
-                    LOG.error("Failed to commit TransactionService transaction", e);
-                    LOG.error("Ignoring...");
-                }
+        final List<Runnable> postCompletionRunnables = RUNNABLES.get();
+
+        if (CollectionUtils.isNotEmpty(postCompletionRunnables)) {
+            if (allRunnables == null) {
+                allRunnables = postCompletionRunnables;
+            } else {
+                allRunnables.addAll(postCompletionRunnables);
             }
+        }
 
-        //}
+        runRunnables(allRunnables);
+
+        RUNNABLES_AFTER_COMMIT.remove();
         RUNNABLES.remove();
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerTransactionSynchronizationAdapter.afterCompletion(status=" + (status == STATUS_COMMITTED ? "COMMITTED" : "ROLLED_BACK") + ")");
+        }
     }
 
+    private boolean registerSynchronization() {
+        final boolean ret = TransactionSynchronizationManager.isSynchronizationActive();
+        if (ret) {
+            List<Runnable> threadRunnablesOnCompletion = RUNNABLES.get();
+            List<Runnable> threadRunnablesOnCommit = RUNNABLES_AFTER_COMMIT.get();
+            if (threadRunnablesOnCompletion == null && threadRunnablesOnCommit == null) {
+                TransactionSynchronizationManager.registerSynchronization(this);
+            }
+        }
+        return ret;
+    }
+
+    private void runRunnables(final List<Runnable> runnables) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerTransactionSynchronizationAdapter.runRunnables()");
+        }
+
+        if (runnables != null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Executing {" + runnables.size() + "} runnables");
+            }
+            try {
+                //Create new  transaction
+                TransactionTemplate txTemplate = new TransactionTemplate(txManager);
+                txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
+
+                txTemplate.execute(new TransactionCallback<Object>() {
+                    public Object doInTransaction(TransactionStatus status) {
+                        for (Runnable runnable : runnables) {
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("Executing runnable {" + runnable + "}");
+                            }
+                            try {
+                                runnable.run();
+                            } catch (RuntimeException e) {
+                                LOG.error("Failed to execute runnable " + runnable, e);
+                                break;
+                            }
+                        }
+
+                        return null;
+                    }
+                });
+            } catch (Exception e) {
+                LOG.error("Failed to commit TransactionService transaction", e);
+                LOG.error("Ignoring...");
+            }
+        } else {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("No runnables to execute");
+            }
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerTransactionSynchronizationAdapter.runRunnables()");
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ranger/blob/fbcaaaf6/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManager.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManager.java b/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManager.java
index 2788a61..8c1cfd8 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManager.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManager.java
@@ -26,6 +26,7 @@ import javax.persistence.PersistenceContext;
 
 import org.apache.log4j.Logger;
 import org.apache.ranger.common.StringUtil;
+import org.apache.ranger.common.db.RangerTransactionSynchronizationAdapter;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -42,6 +43,9 @@ public class RangerDaoManager extends RangerDaoManagerBase {
 	@Autowired
 	StringUtil stringUtil;
 
+	@Autowired
+	RangerTransactionSynchronizationAdapter transactionSynchronizationAdapter;
+
 	@Override
 	public EntityManager getEntityManager() {
 		return em;
@@ -66,4 +70,8 @@ public class RangerDaoManager extends RangerDaoManagerBase {
 		return stringUtil;
 	}
 
+	public RangerTransactionSynchronizationAdapter getRangerTransactionSynchronizationAdapter() {
+		return transactionSynchronizationAdapter;
+	}
+
 }

http://git-wip-us.apache.org/repos/asf/ranger/blob/fbcaaaf6/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java b/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java
index da89e04..5dffc0e 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java
@@ -25,14 +25,8 @@
 
 import javax.persistence.EntityManager;
 
-import org.apache.ranger.common.RESTErrorUtil;
-import org.springframework.beans.factory.annotation.Autowired;
-
-
 public abstract class RangerDaoManagerBase {
 
-	@Autowired
-	protected RESTErrorUtil restErrorUtil;
 	abstract public EntityManager getEntityManager();
 
 	public RangerDaoManagerBase() {

http://git-wip-us.apache.org/repos/asf/ranger/blob/fbcaaaf6/security-admin/src/main/java/org/apache/ranger/db/XXServiceVersionInfoDao.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXServiceVersionInfoDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXServiceVersionInfoDao.java
index e100329..d7e5a86 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXServiceVersionInfoDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXServiceVersionInfoDao.java
@@ -23,6 +23,7 @@ import java.util.List;
 import javax.persistence.NoResultException;
 
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.ranger.biz.ServiceDBStore;
 import org.apache.ranger.common.db.BaseDao;
 import org.apache.ranger.entity.XXServiceVersionInfo;
 import org.springframework.stereotype.Service;
@@ -31,6 +32,7 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class XXServiceVersionInfoDao extends BaseDao<XXServiceVersionInfo> {
+
 	/**
 	 * Default Constructor
 	 */
@@ -122,14 +124,17 @@ public class XXServiceVersionInfoDao extends BaseDao<XXServiceVersionInfo> {
 		}
 
 		for(XXServiceVersionInfo serviceVersionInfo : serviceVersionInfos) {
-			Long currentTagVersion = serviceVersionInfo.getTagVersion();
 
-			if(currentTagVersion == null) {
-				currentTagVersion = Long.valueOf(0);
-			}
+			Runnable commitWork = new Runnable() {
+				@Override
+				public void run() {
+					ServiceDBStore.persistVersionChange(daoManager, serviceVersionInfo.getId(), ServiceDBStore.VERSION_TYPE.TAG_VERSION);
+				}
+			};
+
+			daoManager.getRangerTransactionSynchronizationAdapter().executeOnTransactionCommit(commitWork);
 
-			serviceVersionInfo.setTagVersion(currentTagVersion + 1);
-			serviceVersionInfo.setTagUpdateTime(updateTime);
 		}
+
 	}
 }

http://git-wip-us.apache.org/repos/asf/ranger/blob/fbcaaaf6/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
----------------------------------------------------------------------
diff --git a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
index bd474cc..c9db90a 100644
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
@@ -30,6 +30,7 @@ import org.apache.ranger.common.RangerFactory;
 import org.apache.ranger.common.SearchCriteria;
 import org.apache.ranger.common.StringUtil;
 import org.apache.ranger.common.UserSessionBase;
+import org.apache.ranger.common.db.RangerTransactionSynchronizationAdapter;
 import org.apache.ranger.db.*;
 import org.apache.ranger.entity.*;
 import org.apache.ranger.plugin.model.RangerPolicy;
@@ -138,9 +139,10 @@ public class TestServiceDBStore {
 	
 	@Mock
 	AssetMgr assetMgr;
-	
-	
-	
+
+	@Mock
+	RangerTransactionSynchronizationAdapter transactionSynchronizationAdapter;
+
 	@Rule
 	public ExpectedException thrown = ExpectedException.none();
 
@@ -1056,8 +1058,8 @@ public class TestServiceDBStore {
 	public void test20updateService() throws Exception {
 		XXServiceDao xServiceDao = Mockito.mock(XXServiceDao.class);
 		XXService xService = Mockito.mock(XXService.class);
-		XXServiceVersionInfoDao xServiceVersionInfoDao = Mockito.mock(XXServiceVersionInfoDao.class);
-		XXServiceVersionInfo xServiceVersionInfo = Mockito.mock(XXServiceVersionInfo.class);
+		//XXServiceVersionInfoDao xServiceVersionInfoDao = Mockito.mock(XXServiceVersionInfoDao.class);
+		//XXServiceVersionInfo xServiceVersionInfo = Mockito.mock(XXServiceVersionInfo.class);
 		XXServiceConfigMapDao xServiceConfigMapDao = Mockito
 				.mock(XXServiceConfigMapDao.class);
 		XXServiceConfigDefDao xServiceConfigDefDao = Mockito
@@ -1134,9 +1136,9 @@ public class TestServiceDBStore {
 		Mockito.when(svcService.getPopulatedViewObject(xService)).thenReturn(
 				rangerService);
 
-		Mockito.when(daoManager.getXXServiceVersionInfo()).thenReturn(xServiceVersionInfoDao);
-		Mockito.when(xServiceVersionInfoDao.findByServiceId(Id)).thenReturn(xServiceVersionInfo);
-		Mockito.when(xServiceVersionInfoDao.update(xServiceVersionInfo)).thenReturn(xServiceVersionInfo);
+		//Mockito.when(daoManager.getXXServiceVersionInfo()).thenReturn(xServiceVersionInfoDao);
+		//Mockito.when(xServiceVersionInfoDao.findByServiceId(Id)).thenReturn(xServiceVersionInfo);
+		//Mockito.when(xServiceVersionInfoDao.update(xServiceVersionInfo)).thenReturn(xServiceVersionInfo);
 
 		RangerService dbRangerService = serviceDBStore
 				.updateService(rangerService, options);
@@ -1159,8 +1161,8 @@ public class TestServiceDBStore {
 		XXPolicyDao xPolicyDao = Mockito.mock(XXPolicyDao.class);
 		XXServiceDao xServiceDao = Mockito.mock(XXServiceDao.class);
 		XXService xService = Mockito.mock(XXService.class);
-		XXServiceVersionInfoDao xServiceVersionInfoDao = Mockito.mock(XXServiceVersionInfoDao.class);
-		XXServiceVersionInfo xServiceVersionInfo = Mockito.mock(XXServiceVersionInfo.class);
+		//XXServiceVersionInfoDao xServiceVersionInfoDao = Mockito.mock(XXServiceVersionInfoDao.class);
+		//XXServiceVersionInfo xServiceVersionInfo = Mockito.mock(XXServiceVersionInfo.class);
 		XXPolicyItemDao xPolicyItemDao = Mockito.mock(XXPolicyItemDao.class);
 		XXPolicyItemDataMaskInfoDao xxPolicyItemDataMaskInfoDao = Mockito.mock(XXPolicyItemDataMaskInfoDao.class);
 		XXPolicyItemRowFilterInfoDao xxPolicyItemRowFilterInfoDao = Mockito.mock(XXPolicyItemRowFilterInfoDao.class);
@@ -1327,9 +1329,9 @@ public class TestServiceDBStore {
 		Mockito.when(svcService.getPopulatedViewObject(xService)).thenReturn(
 				rangerService);
 
-		Mockito.when(daoManager.getXXServiceVersionInfo()).thenReturn(xServiceVersionInfoDao);
-		Mockito.when(xServiceVersionInfoDao.findByServiceId(Id)).thenReturn(xServiceVersionInfo);
-		Mockito.when(xServiceVersionInfoDao.update(xServiceVersionInfo)).thenReturn(xServiceVersionInfo);
+		//Mockito.when(daoManager.getXXServiceVersionInfo()).thenReturn(xServiceVersionInfoDao);
+		//Mockito.when(xServiceVersionInfoDao.findByServiceId(Id)).thenReturn(xServiceVersionInfo);
+		//Mockito.when(xServiceVersionInfoDao.update(xServiceVersionInfo)).thenReturn(xServiceVersionInfo);
 
 		Mockito.when(daoManager.getXXPolicyItem()).thenReturn(xPolicyItemDao);
 		Mockito.when(xPolicyItemDao.findByPolicyId(policyItem.getId()))
@@ -1524,9 +1526,9 @@ public class TestServiceDBStore {
 		XXPolicy xPolicy = Mockito.mock(XXPolicy.class);
 		XXPolicyDao xPolicyDao = Mockito.mock(XXPolicyDao.class);
 		XXServiceDao xServiceDao = Mockito.mock(XXServiceDao.class);
-		XXServiceVersionInfoDao xServiceVersionInfoDao = Mockito.mock(XXServiceVersionInfoDao.class);
+		//XXServiceVersionInfoDao xServiceVersionInfoDao = Mockito.mock(XXServiceVersionInfoDao.class);
 		XXService xService = Mockito.mock(XXService.class);
-		XXServiceVersionInfo xServiceVersionInfo = Mockito.mock(XXServiceVersionInfo.class);
+		//XXServiceVersionInfo xServiceVersionInfo = Mockito.mock(XXServiceVersionInfo.class);
 		XXPolicyItemDao xPolicyItemDao = Mockito.mock(XXPolicyItemDao.class);
 
 		XXServiceDef xServiceDef = serviceDef();
@@ -1682,9 +1684,9 @@ public class TestServiceDBStore {
 
 		Mockito.when(daoManager.getXXService()).thenReturn(xServiceDao);
 		Mockito.when(xServiceDao.findByName(name)).thenReturn(xService);
-		Mockito.when(daoManager.getXXServiceVersionInfo()).thenReturn(xServiceVersionInfoDao);
-		Mockito.when(xServiceVersionInfoDao.findByServiceId(Id)).thenReturn(xServiceVersionInfo);
-		Mockito.when(xServiceVersionInfoDao.update(xServiceVersionInfo)).thenReturn(xServiceVersionInfo);
+		//Mockito.when(daoManager.getXXServiceVersionInfo()).thenReturn(xServiceVersionInfoDao);
+		//Mockito.when(xServiceVersionInfoDao.findByServiceId(Id)).thenReturn(xServiceVersionInfo);
+		//Mockito.when(xServiceVersionInfoDao.update(xServiceVersionInfo)).thenReturn(xServiceVersionInfo);
 
 		Mockito.when(svcService.getPopulatedViewObject(xService)).thenReturn(
 				rangerService);
@@ -1763,6 +1765,9 @@ public class TestServiceDBStore {
 				.thenReturn(policyConditionDefObj);
 		Mockito.when(!bizUtil.hasAccess(xService, null)).thenReturn(true);
 
+		//RangerTransactionSynchronizationAdapter spy = Mockito.spy(transactionSynchronizationAdapter);
+		//Mockito.doNothing().when(spy).executeOnTransactionCommit(Mockito.any(Runnable.class));
+
 		RangerPolicy dbRangerPolicy = serviceDBStore.createPolicy(rangerPolicy);
 		Assert.assertNull(dbRangerPolicy);
 		Assert.assertEquals(Id, rangerPolicy.getId());
@@ -1813,10 +1818,10 @@ public class TestServiceDBStore {
 		XXServiceDao xServiceDao = Mockito.mock(XXServiceDao.class);
                 XXPolicyLabelMapDao xPolicyLabelMapDao = Mockito.mock(XXPolicyLabelMapDao.class);
 		XXService xService = Mockito.mock(XXService.class);
-		XXServiceVersionInfoDao xServiceVersionInfoDao = Mockito.mock(XXServiceVersionInfoDao.class);
+		//XXServiceVersionInfoDao xServiceVersionInfoDao = Mockito.mock(XXServiceVersionInfoDao.class);
 		XXServiceDefDao xServiceDefDao = Mockito.mock(XXServiceDefDao.class);
 		XXServiceDef xServiceDef = Mockito.mock(XXServiceDef.class);
-		XXServiceVersionInfo xServiceVersionInfo = Mockito.mock(XXServiceVersionInfo.class);
+		//XXServiceVersionInfo xServiceVersionInfo = Mockito.mock(XXServiceVersionInfo.class);
 		XXPolicyResourceDao xPolicyResourceDao = Mockito
 				.mock(XXPolicyResourceDao.class);
 		XXPolicyResourceMapDao xPolicyResourceMapDao = Mockito
@@ -1883,9 +1888,9 @@ public class TestServiceDBStore {
 		Mockito.when(svcService.getPopulatedViewObject(xService)).thenReturn(
 				rangerService);
 
-		Mockito.when(daoManager.getXXServiceVersionInfo()).thenReturn(xServiceVersionInfoDao);
-		Mockito.when(xServiceVersionInfoDao.findByServiceId(Id)).thenReturn(xServiceVersionInfo);
-		Mockito.when(xServiceVersionInfoDao.update(xServiceVersionInfo)).thenReturn(xServiceVersionInfo);
+		//Mockito.when(daoManager.getXXServiceVersionInfo()).thenReturn(xServiceVersionInfoDao);
+		//Mockito.when(xServiceVersionInfoDao.findByServiceId(Id)).thenReturn(xServiceVersionInfo);
+		//Mockito.when(xServiceVersionInfoDao.update(xServiceVersionInfo)).thenReturn(xServiceVersionInfo);
 
 		Mockito.when(daoManager.getXXServiceDef()).thenReturn(xServiceDefDao);
 		Mockito.when(xServiceDefDao.findByName(rangerService.getType()))
@@ -1960,8 +1965,8 @@ public class TestServiceDBStore {
 		setup();
 		XXServiceDao xServiceDao = Mockito.mock(XXServiceDao.class);
 		XXService xService = Mockito.mock(XXService.class);
-		XXServiceVersionInfoDao xServiceVersionInfoDao = Mockito.mock(XXServiceVersionInfoDao.class);
-		XXServiceVersionInfo xServiceVersionInfo = Mockito.mock(XXServiceVersionInfo.class);
+		//XXServiceVersionInfoDao xServiceVersionInfoDao = Mockito.mock(XXServiceVersionInfoDao.class);
+		//XXServiceVersionInfo xServiceVersionInfo = Mockito.mock(XXServiceVersionInfo.class);
                 XXPolicyLabelMapDao xPolicyLabelMapDao = Mockito.mock(XXPolicyLabelMapDao.class);
 		XXPolicyItemDao xPolicyItemDao = Mockito.mock(XXPolicyItemDao.class);
 		XXPolicyItemDataMaskInfoDao xPolicyItemDataMaskInfoDao = Mockito.mock(XXPolicyItemDataMaskInfoDao.class);
@@ -2136,9 +2141,9 @@ public class TestServiceDBStore {
 		Mockito.when(daoManager.getXXService()).thenReturn(xServiceDao);
 		Mockito.when(xServiceDao.getById(Id)).thenReturn(xService);
 
-		Mockito.when(daoManager.getXXServiceVersionInfo()).thenReturn(xServiceVersionInfoDao);
-		Mockito.when(xServiceVersionInfoDao.findByServiceId(Id)).thenReturn(xServiceVersionInfo);
-		Mockito.when(xServiceVersionInfoDao.update(xServiceVersionInfo)).thenReturn(xServiceVersionInfo);
+		//Mockito.when(daoManager.getXXServiceVersionInfo()).thenReturn(xServiceVersionInfoDao);
+		//Mockito.when(xServiceVersionInfoDao.findByServiceId(Id)).thenReturn(xServiceVersionInfo);
+		//Mockito.when(xServiceVersionInfoDao.update(xServiceVersionInfo)).thenReturn(xServiceVersionInfo);
 
 		Mockito.when(daoManager.getXXService()).thenReturn(xServiceDao);
 		Mockito.when(xServiceDao.getById(rangerService.getId())).thenReturn(
@@ -2150,6 +2155,9 @@ public class TestServiceDBStore {
                                 xPolicyLabelMapDao);
                 Mockito.when(xPolicyLabelMapDao.findByPolicyId(rangerPolicy.getId()))
                                 .thenReturn(xxPolicyLabelMapList);
+		//RangerTransactionSynchronizationAdapter spy = Mockito.spy(transactionSynchronizationAdapter);
+		//Mockito.doNothing().when(spy).executeOnTransactionCommit(Mockito.any(Runnable.class));
+
 
 		serviceDBStore.deletePolicy(Id);
 	}