Откат исключений транзакции Spring Hibernate - PullRequest
0 голосов
/ 09 декабря 2011

Обновление 12/12/2011

Приложение использует общий класс DAO, который можно найти здесь .

На основепри перечитывании весеннего руководства по использованию @Repository может возникнуть необходимость добавить это в мою реализацию GenericDAO, чтобы Spring могла обрабатывать переводы исключений.

Я добавил@ Репозиторий GenericDAO, но результаты не изменились.Родительский объект все еще сохраняется в базе данных.


Используя Spring 2.5.6, JBoss 5.1 с его версией гибернации, Spring MVC, MySQL

Я провожу некоторое тестирование, чтобы убедиться, что мои транзакции будут откатываться правильно всобытие исключения.В приведенном ниже коде второй метод: createProfile вызовет исключение NullPointerException, которое препятствует завершению метода.Я ожидал, что сделка будет отменена.Я обнаружил, что пользовательский объект сохраняется в базе данных.Я хочу, чтобы в случае сбоя второй операции первая операция также должна была откатиться.

Я внес некоторые изменения, в которых я изменил распространение на REQUIRED_NEW для родительского метода, но не увидел никаких изменений.в поведении.

Я включил ведение журнала для весенней транзакции.

Я просматривал различные публикации здесь и просматривал что и весна говорит о транзакциях ,Кажется, я что-то упускаю из-за поведения транзакций.

Что я здесь делаю неправильно.

У меня есть следующее определение

    @Transactional(propagation = Propagation.SUPPORTS)
    public class ProfileServiceImpl implements ProfileService
    {

      @Transactional(propagation=Propagation.REQUIRED, readOnly=false)
      public boolean createProfile(UserDTO pUserDTO, ContactInfoDTO pContactInfoDTO)
        {
            boolean retVal = false;

            if(this.createProfile(pUserDTO))
            {
                if(this.addAddressToUser(pContactInfoDTO, pUserDTO.getId()))
                {
                    retVal = true;
                }
            }
            return retVal;
        }

    @Transactional(propagation=Propagation.REQUIRED, readOnly=false)
    public boolean createProfile(UserDTO userDTO)
    {
        boolean retVal = false;

        if(this.getProfileQueries().isLoginUnique(userDTO.getLogin(),userDTO.getSiteInfoId()))
        {
            User user = new User();
            BeanUtils.copyProperties(userDTO, user);
            user.setPassword(this.stringDigester.digest(userDTO.getPassword()));
            user.setSiteInfo(this.getSiteInfoDao().read(userDTO.getSiteInfoId()));
            user.setSecurityLevel(SecurityLevel.ROLE_USER);
            user.setStatus(Status.ACTIVE);

            Long pk = this.getUserDao().create(user);
            userDTO.setId(pk);

            retVal = true;
        }
        return retVal;
    }
    @Transactional(propagation=Propagation.REQUIRED, readOnly=false)
    public boolean addAddressToUser(ContactInfoDTO pAddress, Long pProfileId)
    {
        boolean retVal = false;

        if(null != pAddress && null != pProfileId)
        {
            ContactInfo contactInfo = new ContactInfo();
            BeanUtils.copyProperties(pAddress, contactInfo);

            User user = this.getUserDao().read(pProfileId);
            contactInfo.setUser(user);
            this.getContactInfoDao().create(contactInfo);

            user.getUserAddress().setProfileAddress(contactInfo);
            user.getUserAddress().setBillingAddress(contactInfo);
            this.getUserDao().update(user);

            retVal = true;

        }
        return retVal;
    }
}

Конфигурация данных

      <!-- TRANSACTION MANAGER--> 
      <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
      </bean>

      <!-- ANNOTATION DRIVEN TRANSACTIONS -->
      <tx:annotation-driven transaction-manager="transactionManager" />


  <bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:/MySqlDS"/>
  </bean>

  <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="jndiDataSource"/>
    <property name="annotatedClasses">
      <list>
        <value>com.vsg.dataaccess.user.entity.User</value>
        <value>com.vsg.dataaccess.user.entity.ContactInfo</value>
        <value>com.vsg.dataaccess.user.entity.UserAddress</value>
     </list>
    </property>


    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
        <prop key="hibernate.hbm2ddl.auto">update</prop>
        <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
        <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
        <prop key="hibernate.use_sql_comments">${hibernate.use_sql_comments}</prop>
        <prop key="hibernate.jdbc.batch_size">20</prop>
        <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
        <prop key="net.sf.ehcache.configurationResourceName">ehcache.xml</prop>
        <prop key="hibernate.cache.use_second_level_cache">true</prop>
        <prop key="hibernate.cache.use_structured_entries">true</prop>
        <prop key="hibernate.cache.use_query_cache">true</prop>
        <prop key="hibernate.generate_statistics">true</prop>
        <prop key="org.hibernate.envers.audit_table_suffix">_aud</prop>
        <prop key="org.hibernate.envers.revision_field_name">rev_number</prop>
        <prop key="org.hibernate.envers.revision_type_field_name">rev_type</prop>
        <prop key="org.hibernate.envers.revision_on_collection_change">true</prop>        
      </props>
    </property>
    <property name="entityInterceptor">
      <bean class="vsg.ecotrak.dataaccess.framework.hibernate.interceptor.AuditTrailInterceptor"/>
    </property>
  </bean>

Ответы [ 2 ]

0 голосов
/ 15 декабря 2011

Я думаю, что автокоммит вызывает проблему. Вы хотели бы отключить его и вручную управлять транзакциями, если вы хотите выполнить откат по первому запросу при сбое второго. В противном случае первый запрос будет отправлен автоматически. Подумай об этом.

0 голосов
/ 09 декабря 2011

Убедитесь (в режиме отладки в IDE), что экземпляр класса ProfileServiceImpl обернут прокси Spring AOP (это будет означать, что Spring Transaction настроен правильно), а также укажите * .xml конфигурацию менеджера транзакций и источника данных (и т. Д.).)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...