Jackrabbit + Spring JTA交易不起作用

时间:2015-07-09 21:27:10

标签: java spring transactions spring-transactions jackrabbit

我正在尝试使用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,让它由我需要的所有类执行。

0 个答案:

没有答案