Results 1 to 7 of 7

Thread: EJB + Spring + Transactions

  1. #1
    Join Date
    Feb 2008
    Posts
    17

    Question EJB + Spring + Transactions

    I am trying to get Transactions working in the following scenario:

    SSB (with CMT) --> POJO (Injected with JMSTtemplate) --> Sends JMS Msg

    I have looked up the XA connection factory from weblogic and injected the JMS template with it. I expect the JMS message to be put on the queue only when i commit in the SSB. When i setRollbackonly to true in the SSB, i expect the JMS message not to be put on the queue. However that doesnt seem to happen. The message is put on the queue even when i rollback in the SSB.

    How do i get Spring to participate in the Transaction from the SSB?

    Here is the configuration:

    Code:
    ejb-jar.xml
    
        <enterprise-beans>
            <session>
                <display-name>PMSimulator</display-name>
                <ejb-name>PMSimulator</ejb-name>
                <home>com.abc.xyz.pmsimulator.PMSimulatorHome</home>
                <remote>com.abc.xyz.pmsimulator.PMSimulatorRemote</remote>
                <ejb-class>com.abc.xyz.pmsimulator.PMSimulatorBean</ejb-class>
                <session-type>Stateless</session-type>
                <transaction-type>Container</transaction-type>
                <resource-ref>
                    <res-ref-name>jms/mqwmcappqm1xaqcf</res-ref-name>
                    <res-type>javax.jms.QueueConnectionFactory</res-type>
                    <res-auth>Container</res-auth>
                    <res-sharing-scope>Shareable</res-sharing-scope>
                </resource-ref>
                <resource-env-ref>
                    <resource-env-ref-name>
                        jms/pm.submission.to.tg</resource-env-ref-name>
                    <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
                </resource-env-ref>
            </session>
        </enterprise-beans>
    
        <assembly-descriptor>
            <container-transaction>
                <method>
                    <ejb-name>PMSimulator</ejb-name>
                   <method-name>*</method-name>
                </method>
                <trans-attribute>Required</trans-attribute>
            </container-transaction>
        </assembly-descriptor>
    
    
    Weblogic-ejb-jar.xml
    
        <weblogic-enterprise-bean>
            <ejb-name>PMSimulator</ejb-name>
            <transaction-descriptor>
                <trans-timeout-seconds>3600</trans-timeout-seconds>
            </transaction-descriptor>
            <reference-descriptor>
                <resource-description>
                    <res-ref-name>jms/mqwmcappqm1xaqcf</res-ref-name>
                    <jndi-name>mqwmcappqm1xaqcf</jndi-name>
                </resource-description>
                <resource-env-description>
                    <res-env-ref-name>
                        jms/pm.submission.to.tg</res-env-ref-name>
                    <jndi-name>pm.submission.to.tg</jndi-name>
                </resource-env-description>
            </reference-descriptor>
            <enable-call-by-reference>true</enable-call-by-reference>
            <jndi-name>PMSimulator</jndi-name>
        </weblogic-enterprise-bean>
    
    
    Spring Context
    
    
        <!-- Define XA Connection Factory -->
    
        <bean id="common.messaging.XAConnectionFactory"
            class="org.springframework.jndi.JndiObjectFactoryBean" lazy-init="true">
            <property name="jndiName" value="mqwmcappqm1xaqcf"/>
        </bean>
    
        <!-- Define Transaction Manager -->
        <bean id="transactionManager"
            class="org.springframework.transaction.jta.WebLogicJtaTransactionManager" lazy-init="true">
        </bean>
    
        <!-- Enlist Transactional Resources -->
        <bean id="TransactionProxy"
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init="true">
            <property name="transactionManager">
                <ref bean="transactionManager"/>
            </property>
            <property name="transactionAttributes">
                <props>
                    <prop key="*">PROPAGATION_REQUIRED</prop>
                </props>
            </property>
        </bean>

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    1) Your TransactionProxy is useless, is doesn't do anything.
    2) Make sure your service call is transactional, currently I see no transactional service.
    3) Make sure you use the transactional service and not the unproxied instance..
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Feb 2008
    Posts
    17

    Default

    Marten,

    Thanks for your response.

    Since i am pretty new to Spring (Transactions), and couldn't find many examples around this on the internet, i was pretty much suspecting my spring configuration.

    Questions on your response:

    1. Why do you think the ProxyBean is not required? Isnt the proxy bean supposed to be wiring together the TransactionManager, Target (POJO) & also define the Transaction Attributes?

    Code:
        <bean id="MessageSender"
    class="com.abc.xyz.client.MessageSender">
            <property name="jmsTemplate" ref="jmsTemplate"/>
        </bean>
    
        <bean id="TransactionProxy"     class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
            lazy-init="true">
            <property name="transactionManager">
                <ref bean="transactionManager"/>
            </property>
            <property name="target">
                <ref local="MessageSender"/>
            </property>
            <property name="transactionAttributes">
                <props>
                    <prop key="commit*">PROPAGATION_MANDATORY</prop>
                </props>
            </property>
        </bean>
    2. Could you please be a little more specific when you say service call should be transactional? Isnt the SSB operating within the scope of a transaction created by the container?

    It would really helpful, if there is an example that you could point me to.
    Last edited by silverdream; Jun 2nd, 2008 at 05:57 PM.

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    1. Why do you think the ProxyBean is not required? Isnt the proxy bean supposed to be wiring together the TransactionManager, Target (POJO) & also define the Transaction Attributes?
    The sample you first posted didn't contain a target, so was pretty useless. Next to that you need to USE the proxy instead of the unproxied bean. So instead of using the MessageSender you need to use the TransactionProxy. (Chapter of the reference guide 6 explains proxies and spring aop in detail!).
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5
    Join Date
    Feb 2008
    Posts
    17

    Default

    Marten,

    I understood the part about using the ProxyBean instead of the Unproxied Bean. Thank you for helping out.

    That apart, doing some more reading, i figured out that inorder to use the transaction from weblogic, all i needed to do was to lookup the connectionfactory from JNDI and that was enough for Spring to use that transaction to send the message. I didnt have to define the TransactionManager & ProxyBean in spring to use the transaction.

    http://dev2dev.bea.com/blog/maximdim...ssaging_w.html

    I tested this out with JMSTemplate102 and MQXAQueueConnectionFactory and i am able to test a 2 phase commit successfully.

    However when i try to use the unified MQXAConnectionFactory, the rollback doesn't seem to work. The message is still put on the queue when i set the ctx.setRollbackOnly.

    If i go back to use MQXAQueueConnectionFactory, 2PC works again.

    This problem is driving me nuts. I think its more of a question in the Bea forums but just thought i will give it a shot here.

    BTW, i have the following question:

    If i dont need to use WeblogicJTATransactionManager and not define the ProxyBean in this scenario to support transaction, then which scenario do these get used?

  6. #6
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    You need a JTA transactionmanager configured, else spring will not detect any transaction. However your configuration can be simplyfied. By using the tx and aop namespaces.

    Code:
    <tx:jta-transaction-manager/>
    
    <tx:advice id="txAdvice>
      <tx:attributes>
        <tx:method name="commit*" propagation="REQUIRED" />
      </tx:attributes>
    </tx:advice>
    
    <aop:config>
      <aop:pointcut id="serviceMethods" expression="execution(* com.mycompane.*Service.*(..))" />
      <aop:advice pointcut-ref="serviceMethods" advice-ref="txAdvice" />
    </aop:config>
    The above is way shorter and easier then define a TransactionalProxy for all your beans.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  7. #7
    Join Date
    Feb 2008
    Posts
    17

    Default

    For some reason, i didnt need to define a TransactionManager in Spring to participate in the Transaction from Weblogic. It works perfectly fine with a QueueConnectionFactory.

    When i switch to ConnectionFactory, it does not participate in the Transaction even if i define the Transaction Manager.

    Has anyone tried testing this configuration with Websphere MQ?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •