Results 1 to 3 of 3

Thread: EJB tranaction to propage to LDAP

  1. #1
    Join Date
    Dec 2011
    Posts
    14

    Default EJB tranaction to propage to LDAP

    Hi,
    I am using Spring LDAP transaction manager(org.springframework.ldap.transaction.compe nsating.manager.ContextSourceTransactionManager) to manager LDAP inserts and updates, this part is working as expected, if I try to insert duplicates in the same transactional insert, first insert is rolled back upon second failing.
    However I want LDAP transaction to participate in an EJB transaction. That is, these LDAP operations are invoked by a Stateless session bean with @TransactionAttribute(TransactionAttributeType.REQ UIRED), and I expected any failure in the EJB transaction to roll back the LDAP as well, but it is not to be. LDAP does not seem to hook into EJB transaction. Is this something that can be achieved provided that LDAP is non-XA?.
    Any ideas really appreciated!
    springldap.xml:
    Code:
    <bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource">
          <property name="url" value="ldap://localhost:389" />
          <property name="base" value="dc=maxcrc,dc=com" />
          <property name="userDn" value="cn=Manager,dc=maxcrc,dc=com" />
          <property name="password" value="secret" />
       </bean>
    
       <bean id="contextSource" 
        class="org.springframework.ldap.transaction.compensating.manager.TransactionAwareContextSourceProxy">
          <constructor-arg ref="contextSourceTarget" />
       </bean>
       
       <bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
          <constructor-arg ref="contextSource" />
       </bean>
       
       <bean id="transactionManager" 
        class="org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManager">
          <property name="contextSource" ref="contextSource" />
       </bean>
    
       <bean id="myDataAccessObjectTarget" class="model.LDAPContactDAO">
          <property name="ldapTemplate" ref="ldapTemplate" />
       </bean>
       
       <bean id="myDataAccessObject" 
                class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
          <property name="transactionManager" ref="transactionManager" />
          <property name="target" ref="myDataAccessObjectTarget" />
          <property name="transactionAttributes">
             <props>
                <prop key="*">PROPAGATION_REQUIRED</prop>
             </props>
          </property>
       </bean>
    
    EJB method
        @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
        public String getResult() {
            ApplicationContext ctx  = new FileSystemXmlApplicationContext("C:\\springldap.xml");
            ContactDAO dao = (ContactDAO)ctx.getBean("myDataAccessObject");
            dao.insertContact(new ContactDTO("User3","V2"));
            dao.insertContact(new ContactDTO("User3","V2"));
            return "OK";
        }
    If the duplication happens inside ContactDAOImpl.insertContact() ldap is properly rolled back
    Last edited by Chifer; Dec 8th, 2011 at 05:22 AM.

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

    Default

    Please use [ code][/code ] tags when posting code, that way it remains readable.

    You cannot have a non-XA resource participate in a distributed transaction. Next to that LDAP isn't even transactional, there is some trickery inside the ContextSourceTransactionManager to emulate transactions (the compensating part that is).

    Code:
    @TransactionAttribute(TransactionAttributeType.REQ UIRES_NEW)
    public String getResult() {
      ApplicationContext ctx = new FileSystemXmlApplicationContext("C:\\springldap.xm l");
      ContactDAO dao = (ContactDAO)ctx.getBean("myDataAccessObject");
      dao.insertContact(new ContactDTO("User3","V2"));
      dao.insertContact(new ContactDTO("User3","V2"));
      return "OK";
    }
    I really hope that this isn't production code. NEVER create an application context inside a method just for the purpose of getting a bean, UNLESS you want to have memory and performance issues.

    You might get something hacked together but for that you need spring to manage/drive your transactions and not your container.
    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
    Dec 2011
    Posts
    14

    Default

    Hi

    Thanks for your explanation, this is what I suspected as well after reading few documents. I guess one way out of this would be to use
    Code:
    org.springframework.ldap.transaction.compensating.manager.ContextSourceAndDataSourceTransactionManager
    and tie the db and ldap transactions together. Unfortunately I don't have that liberty.

    Regarding, creating app context in EJB method, this is not production code,but test code written just to POC the LDAP transaction behavior.

Tags for this Thread

Posting Permissions

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