我正在尝试使用Spring配置Jackrabbit来使用事务。对于我已经研究过的内容,我需要JCA类来管理远程存储库,因此,我使用的是Jencks,这是最常用的实现方法。
但是,在测试时,我无法使交易有效。
这是我的配置文件:
<!-- JCA Transaction Manager Implementation -->
<bean id="txManagerJencks" class="org.jencks.factory.TransactionManagerFactoryBean" />
<!-- JCA Connection Manager Implementation -->
<bean id="pooledConnectionManagerJcr" class="org.jencks.factory.ConnectionManagerFactoryBean">
<property name="transactionManager" ref="txManagerJencks" />
<property name="transaction" value="xa" />
<property name="poolMinSize" value="${jcr.transactions.pool.min.size}"/>
<property name="poolMaxSize" value="${jcr.transactions.pool.max.size}"/>
<property name="connectionMaxIdleMinutes" value="${jcr.transactions.connection.max.idle.minutes}" />
</bean>
<!-- JCA Managed Repository -->
<bean id="repositoryManagedConnectionFactory" class="org.apache.jackrabbit.jca.JCAManagedConnectionFactory" destroy-method="finalize">
<property name="repositoryURI" value="${jcr.server.rmi.url}" />
<property name="bindSessionToTransaction" value="true" />
<property name="startRepositoryImmediately" value="false" />
</bean>
<!-- Repository Configuration -->
<bean id="jcrRepository" class="org.springframework.jca.support.LocalConnectionFactoryBean">
<property name="managedConnectionFactory" ref="repositoryManagedConnectionFactory"/>
<property name="connectionManager" ref="pooledConnectionManagerJcr"/>
</bean>
<!-- JCR Credentials -->
<bean id="jcrCredentials" class="javax.jcr.SimpleCredentials">
<constructor-arg index="0" value="${jcr.user}"/>
<constructor-arg index="1">
<bean factory-bean="jcrCredentialsPassword" factory-method="toCharArray"/>
</constructor-arg>
</bean>
<bean id="jcrCredentialsPassword" class="java.lang.String">
<constructor-arg index="0" value="${jcr.user}"/>
</bean>
<!-- JCR Session Factory -->
<bean id="jcrSessionFactory" class="org.springmodules.jcr.JcrSessionFactory">
<property name="repository" ref="jcrRepository"/>
<property name="credentials" ref="jcrCredentials"/>
<property name="workspaceName" value="${jcr.workspace}"/>
<property name="sessionHolderProviderManager">
<bean class="com.jetsonsys.jcr.support.SingleRepositorySessionHolderProviderManager">
<property name="sessionProvider">
<bean class="org.springmodules.jcr.jackrabbit.support.JackRabbitSessionHolderProvider"/>
</property>
</bean>
</property>
</bean>
<!-- Edit: This fixed the problem -->
<!-- JTA transactional advice (what 'happens') -->
<tx:advice id="txAdviceJCA" transaction-manager="txManagerJencks">
<tx:attributes>
<!-- All methods starting with 'get', 'has' and 'validate' are read-only -->
<tx:method name="get*" read-only="true"/>
<tx:method name="test*" read-only="true"/>
<!-- Other methods use the default transaction settings (see below) -->
<tx:method name="*" rollback-for="java.lang.Exception"/>
</tx:attributes>
</tx:advice>
<!-- AOP. Ensure that the above transactional advice runs for any execution of an operation defined in the com.jetsonsys.plm.cms package -->
<aop:config>
<aop:pointcut id="plmRepositoryServiceOperation" expression="execution(* com.jetsonsys.plm.cms.*RepositoryService.*(..))"/>
<aop:advisor advice-ref="txAdviceJCA" pointcut-ref="plmRepositoryServiceOperation"/>
</aop:config>
RepositoryDAO看起来像是为了获得会话:
@Autowired
private JcrSessionFactory jcrSessionFactory;
/**
* Initializes the session for all the class methods.
*/
Session getSession() throws DAOException {
try {
Session session = jcrSessionFactory.getSession();
return session;
} catch (RepositoryException ex) {
log.error("Error creating JCR Session. [{}]", ex.getMessage());
throw new DAOException(ex.getMessage(), ErrorCode.REPOSITORY_SESSION);
}
}
尝试删除节点然后抛出异常以进行回滚的RepositoryService:
/**
* Deletes a Deal from the Repository.
*
* @param dealId
* @throws PLMException
*/
public void deleteDeal(String dealId) throws PLMException {
if (log.isDebugEnabled()) {
log.debug("Deleting deal from repository [dealId = {}]", dealId);
}
Session session = null;
try {
session = repositoryDAO.getSession();
Node dealsNode = getDealsNode(session);
String dealNodeName = RepositoryConstants.DEAL_NODE_PREFIX + dealId;
repositoryDAO.deleteFolder(dealsNode, dealNodeName);
session.save();
throw new Exception("TESTTTTT");
} catch (Exception ex) {
log.error("Error deleting the Deal {}. {}", dealId, ex.getMessage());
throw new ServiceException(String.format("Error deleting the Deal %s. %s", dealId, ex.getMessage()), ErrorCode.REPOSITORY_DELETE);
} finally {
if (session != null) {
session.logout();
}
}
}
此处的预期结果是抛出异常并且Node保留在存储库中,但节点始终被删除。
我正在尝试使用Spring查找Jackrabbit TX的配置示例,但我发现的那些使用了非常旧版本的库。
我正在使用:
春季4.1.6
Jackrabbit 2.10
Jencks 2.2
提前感谢您的帮助。
-Alejandro
*************************************
*编辑*
*************************************周一
搞定了!只需为Jencks Transaction添加一个Transactional Advice,然后添加一个Aspect,让它由我需要的所有类执行。