Fix AR-649.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3121 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
David Caruana
2006-06-15 17:58:03 +00:00
parent 97425c7177
commit 43a69ac371
6 changed files with 121 additions and 31 deletions

View File

@@ -105,11 +105,16 @@
<ref bean="sessionFactory" /> <ref bean="sessionFactory" />
</property> </property>
</bean> </bean>
<bean id="dbNodeDaoServiceTxnRegistration" class="org.alfresco.repo.transaction.NodeDaoServiceTransactionInterceptor" > <bean id="dbNodeDaoServiceTxnRegistration" class="org.alfresco.repo.transaction.TransactionalDaoInterceptor" >
<property name="nodeDaoService"> <property name="daoService">
<ref bean="nodeDaoServiceImpl" /> <ref bean="nodeDaoServiceImpl" />
</property> </property>
</bean> </bean>
<bean id="persmissionDaoServiceTxnRegistration" class="org.alfresco.repo.transaction.TransactionalDaoInterceptor" >
<property name="daoService">
<ref bean="permissionsDaoComponent" />
</property>
</bean>
<bean id="nodeDaoService" class="org.springframework.aop.framework.ProxyFactoryBean"> <bean id="nodeDaoService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"> <property name="proxyInterfaces">
<value>org.alfresco.repo.node.db.NodeDaoService</value> <value>org.alfresco.repo.node.db.NodeDaoService</value>

View File

@@ -35,10 +35,12 @@ import org.alfresco.repo.security.permissions.impl.PermissionsDaoComponent;
import org.alfresco.repo.security.permissions.impl.SimpleNodePermissionEntry; import org.alfresco.repo.security.permissions.impl.SimpleNodePermissionEntry;
import org.alfresco.repo.security.permissions.impl.SimplePermissionEntry; import org.alfresco.repo.security.permissions.impl.SimplePermissionEntry;
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference; import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
import org.alfresco.repo.transaction.TransactionalDao;
import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.hibernate.Query; import org.hibernate.Query;
import org.hibernate.Session; import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.HibernateCallback;
@@ -52,7 +54,7 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
* *
* @author andyh * @author andyh
*/ */
public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements PermissionsDaoComponent public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements PermissionsDaoComponent, TransactionalDao
{ {
private static final boolean INHERIT_PERMISSIONS_DEFAULT = true; private static final boolean INHERIT_PERMISSIONS_DEFAULT = true;
public static final String QUERY_GET_PERMISSION = "permission.GetPermission"; public static final String QUERY_GET_PERMISSION = "permission.GetPermission";
@@ -61,9 +63,68 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
private NodeDaoService nodeDaoService; private NodeDaoService nodeDaoService;
/** a uuid identifying this unique instance */
private String uuid;
/**
*
*/
public PermissionsDaoComponentImpl() public PermissionsDaoComponentImpl()
{ {
super(); this.uuid = GUID.generate();
}
/**
* Checks equality by type and uuid
*/
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
else if (!(obj instanceof PermissionsDaoComponentImpl))
{
return false;
}
PermissionsDaoComponentImpl that = (PermissionsDaoComponentImpl) obj;
return this.uuid.equals(that.uuid);
}
/**
* @see #uuid
*/
public int hashCode()
{
return uuid.hashCode();
}
/**
* Does this <tt>Session</tt> contain any changes which must be
* synchronized with the store?
*
* @return true => changes are pending
*/
public boolean isDirty()
{
// create a callback for the task
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
return session.isDirty();
}
};
// execute the callback
return ((Boolean)getHibernateTemplate().execute(callback)).booleanValue();
}
/**
* Just flushes the session
*/
public void flush()
{
getSession().flush();
} }
public void setNodeDaoService(NodeDaoService nodeDaoService) public void setNodeDaoService(NodeDaoService nodeDaoService)

View File

@@ -35,6 +35,7 @@ import org.alfresco.repo.domain.hibernate.NodeStatusImpl;
import org.alfresco.repo.domain.hibernate.StoreImpl; import org.alfresco.repo.domain.hibernate.StoreImpl;
import org.alfresco.repo.node.db.NodeDaoService; import org.alfresco.repo.node.db.NodeDaoService;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.TransactionalDao;
import org.alfresco.service.cmr.dictionary.InvalidTypeException; import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
@@ -54,7 +55,7 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
* *
* @author Derek Hulley * @author Derek Hulley
*/ */
public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements NodeDaoService public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements NodeDaoService, TransactionalDao
{ {
private static final String QUERY_GET_ALL_STORES = "store.GetAllStores"; private static final String QUERY_GET_ALL_STORES = "store.GetAllStores";
private static final String QUERY_GET_CONTENT_DATA_STRINGS = "node.GetContentDataStrings"; private static final String QUERY_GET_CONTENT_DATA_STRINGS = "node.GetContentDataStrings";

View File

@@ -24,10 +24,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.node.db.NodeDaoService;
import org.alfresco.repo.node.integrity.IntegrityChecker; import org.alfresco.repo.node.integrity.IntegrityChecker;
import org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcher; import org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcher;
import org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcherFactory;
import org.alfresco.service.cmr.rule.RuleService; import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@@ -107,8 +105,8 @@ public abstract class AlfrescoTransactionSupport
{ {
TransactionSynchronizationImpl synch = getSynchronization(); TransactionSynchronizationImpl synch = getSynchronization();
Set<NodeDaoService> services = synch.getNodeDaoServices(); Set<TransactionalDao> services = synch.getDaoServices();
for (NodeDaoService service : services) for (TransactionalDao service : services)
{ {
if (service.isDirty()) if (service.isDirty())
{ {
@@ -196,20 +194,20 @@ public abstract class AlfrescoTransactionSupport
* This method can be called repeatedly as long as the service being bound * This method can be called repeatedly as long as the service being bound
* implements <tt>equals</tt> and <tt>hashCode</tt>. * implements <tt>equals</tt> and <tt>hashCode</tt>.
* *
* @param nodeDaoService * @param daoService
*/ */
public static void bindNodeDaoService(NodeDaoService nodeDaoService) public static void bindDaoService(TransactionalDao daoService)
{ {
// get transaction-local synchronization // get transaction-local synchronization
TransactionSynchronizationImpl synch = getSynchronization(); TransactionSynchronizationImpl synch = getSynchronization();
// bind the service in // bind the service in
boolean bound = synch.getNodeDaoServices().add(nodeDaoService); boolean bound = synch.getDaoServices().add(daoService);
// done // done
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logBoundService(nodeDaoService, bound); logBoundService(daoService, bound);
} }
} }
@@ -321,7 +319,7 @@ public abstract class AlfrescoTransactionSupport
* <p> * <p>
* The flush may include: * The flush may include:
* <ul> * <ul>
* <li>{@link NodeDaoService#flush()}</li> * <li>{@link TransactionalDao#flush()}</li>
* <li>{@link RuleService#executePendingRules()}</li> * <li>{@link RuleService#executePendingRules()}</li>
* <li>{@link IntegrityChecker#checkIntegrity()}</li> * <li>{@link IntegrityChecker#checkIntegrity()}</li>
* </ul> * </ul>
@@ -425,7 +423,7 @@ public abstract class AlfrescoTransactionSupport
private static class TransactionSynchronizationImpl extends TransactionSynchronizationAdapter private static class TransactionSynchronizationImpl extends TransactionSynchronizationAdapter
{ {
private final String txnId; private final String txnId;
private final Set<NodeDaoService> nodeDaoServices; private final Set<TransactionalDao> daoServices;
private final Set<IntegrityChecker> integrityCheckers; private final Set<IntegrityChecker> integrityCheckers;
private final Set<LuceneIndexerAndSearcher> lucenes; private final Set<LuceneIndexerAndSearcher> lucenes;
private final Set<TransactionListener> listeners; private final Set<TransactionListener> listeners;
@@ -439,7 +437,7 @@ public abstract class AlfrescoTransactionSupport
public TransactionSynchronizationImpl(String txnId) public TransactionSynchronizationImpl(String txnId)
{ {
this.txnId = txnId; this.txnId = txnId;
nodeDaoServices = new HashSet<NodeDaoService>(3); daoServices = new HashSet<TransactionalDao>(3);
integrityCheckers = new HashSet<IntegrityChecker>(3); integrityCheckers = new HashSet<IntegrityChecker>(3);
lucenes = new HashSet<LuceneIndexerAndSearcher>(3); lucenes = new HashSet<LuceneIndexerAndSearcher>(3);
listeners = new HashSet<TransactionListener>(5); listeners = new HashSet<TransactionListener>(5);
@@ -452,12 +450,12 @@ public abstract class AlfrescoTransactionSupport
} }
/** /**
* @return Returns a set of <tt>NodeDaoService</tt> instances that will be called * @return Returns a set of <tt>TransactionalDao</tt> instances that will be called
* during end-of-transaction processing * during end-of-transaction processing
*/ */
public Set<NodeDaoService> getNodeDaoServices() public Set<TransactionalDao> getDaoServices()
{ {
return nodeDaoServices; return daoServices;
} }
/** /**
@@ -500,7 +498,7 @@ public abstract class AlfrescoTransactionSupport
StringBuilder sb = new StringBuilder(50); StringBuilder sb = new StringBuilder(50);
sb.append("TransactionSychronizationImpl") sb.append("TransactionSychronizationImpl")
.append("[ txnId=").append(txnId) .append("[ txnId=").append(txnId)
.append(", node service=").append(nodeDaoServices.size()) .append(", daos=").append(daoServices.size())
.append(", integrity=").append(integrityCheckers.size()) .append(", integrity=").append(integrityCheckers.size())
.append(", indexers=").append(lucenes.size()) .append(", indexers=").append(lucenes.size())
.append(", resources=").append(resources) .append(", resources=").append(resources)
@@ -525,9 +523,9 @@ public abstract class AlfrescoTransactionSupport
listener.flush(); listener.flush();
} }
// flush changes // flush changes
for (NodeDaoService nodeDaoServices : getNodeDaoServices()) for (TransactionalDao daoService : getDaoServices())
{ {
nodeDaoServices.flush(); daoService.flush();
} }
} }

View File

@@ -0,0 +1,26 @@
package org.alfresco.repo.transaction;
/**
* Contract for a DAO to interact with a transaction.
*
* @author davidc
*/
public interface TransactionalDao
{
/**
* Allows the dao to flush any consuming resources. This mechanism is
* used primarily during long-lived transactions to ensure that system resources
* are not used up.
* <p>
* This method must not be used for implementing business logic.
*/
void flush();
/**
* Are there any pending changes which must be synchronized with the store?
*
* @return true => changes are pending
*/
public boolean isDirty();
}

View File

@@ -17,7 +17,6 @@
package org.alfresco.repo.transaction; package org.alfresco.repo.transaction;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.node.db.NodeDaoService;
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
@@ -31,16 +30,16 @@ import org.springframework.beans.factory.InitializingBean;
* *
* @author Derek Hulley * @author Derek Hulley
*/ */
public class NodeDaoServiceTransactionInterceptor implements MethodInterceptor, InitializingBean public class TransactionalDaoInterceptor implements MethodInterceptor, InitializingBean
{ {
private NodeDaoService nodeDaoService; private TransactionalDao daoService;
/** /**
* @param nodeDaoService the <tt>NodeDaoService</tt> to register * @param daoService the <tt>NodeDaoService</tt> to register
*/ */
public void setNodeDaoService(NodeDaoService nodeDaoService) public void setDaoService(TransactionalDao daoService)
{ {
this.nodeDaoService = nodeDaoService; this.daoService = daoService;
} }
/** /**
@@ -48,15 +47,15 @@ public class NodeDaoServiceTransactionInterceptor implements MethodInterceptor,
*/ */
public void afterPropertiesSet() throws Exception public void afterPropertiesSet() throws Exception
{ {
if (nodeDaoService == null) if (daoService == null)
{ {
throw new AlfrescoRuntimeException("NodeDaoService is required: " + this); throw new AlfrescoRuntimeException("TransactionalDao is required: " + this);
} }
} }
public Object invoke(MethodInvocation invocation) throws Throwable public Object invoke(MethodInvocation invocation) throws Throwable
{ {
AlfrescoTransactionSupport.bindNodeDaoService(nodeDaoService); AlfrescoTransactionSupport.bindDaoService(daoService);
// propogate the call // propogate the call
return invocation.proceed(); return invocation.proceed();
} }