Аннотация Распространение.НИКОГДА не работает

Программисты! Я не понимаю, как работает атрибут propagation в аннотации @Transactional. Пожалуйста помоги)

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="packagesToScan" value="com.springapp.mvc"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.jdbc.batch_size">10</prop>
                <prop key="hibernate.max_fetch_depth">3</prop>
                <prop key="jdbc.fetch_size">50</prop>
                <prop key="hbm2ddl.auto">create-drop</prop>
            </props>
        </property>
        <property name = "dataSource" ref = "dataSource"></property>
    </bean>

Класс обслуживания:

   @Service
   public class BookManager implements IBookManager {

      @Autowired
      private  SessionFactory  sessionFactory;

      @Override
      @Transactional(propagation = Propagation.REQUIRES_NEW)
      public void method1() {
          Session session = sessionFactory.getCurrentSession();
          Book book = (Book) session.load(Book.class, 1);
          System.out.println("first: " + book.getTitle());
         method2();
      }

      @Override
      @Transactional(propagation = Propagation.NEVER)
      public void method2() {
            System.out.println("hello");
     }
 }

Я ожидаю, что метод method2() вызовет исключение, так как он помечен Propagation.NEVER. Но этого не происходит.

Выход

 июн 27, 2015 3:35:35 PM org.hibernate.dialect.Dialect <init>
 INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
 июн 27, 2015 3:35:35 PM  org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
 INFO: HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
 июн 27, 2015 3:35:36 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
 INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
 июн 27, 2015 3:35:36 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
 INFO: HHH000397: Using ASTQueryTranslatorFactory
 июн 27, 2015 3:35:36 PM org.springframework.orm.hibernate4.HibernateTransactionManager           afterPropertiesSet
 INFO: Using DataSource [org.apache.commons.dbcp.BasicDataSource@6c5945a7] of Hibernate SessionFactory for HibernateTransactionManager
 Hibernate: select book0_.id as id1_0_0_, book0_.title as title2_0_0_ from books book0_ where book0_.id=?
 first: 33
 hello

 Process finished with exit code 0

Почему это не работает?

Спасибо :)


person Konstantin B.    schedule 27.06.2015    source источник
comment
Было бы здорово, если бы вы могли добавить трассировку стека исключений и перечислить решения, которые вы уже пробовали.   -  person Viraj Nalawade    schedule 27.06.2015
comment
@VirajNalawade, посмотрите, что происходит на консоли   -  person Konstantin B.    schedule 27.06.2015


Ответы (1)


Транзакции в Spring основаны на прокси: когда bean-компонент A вызывает транзакционный bean-компонент B, он фактически вызывает метод динамического прокси-сервера, который имеет дело с открытием транзакции, затем делегирует фактический bean-компонент B, а затем обрабатывает фиксацию. /откат транзакции.

Если вы вызываете метод2 из метода1 одного компонента A, ваш вызов больше не перехватывается транзакционным прокси-сервером, и Spring, таким образом, совершенно не знает, что был вызван метод2(). Так что ничто не может проверить, что нет транзакции.

Поместите метод2 в другой bean-компонент, внедрите его в BookManager, и все заработает, как ожидалось.

person JB Nizet    schedule 27.06.2015
comment
Спасибо! Ваш вариант действительно работает. Еще читал документацию, что еще один способ решения моей проблемы следующий: ‹tx:annotation-driven mode=aspectj/› В результате получаю следующую трассировку стека: xception in thread main org.hibernate.HibernateException: Не удалось получить сеанс, синхронизированный с транзакцией для текущего потока. Может подскажете, что я делаю неправильно? - person Konstantin B.; 27.06.2015
comment
Без понятия. Я никогда не использую этот режим. - person JB Nizet; 27.06.2015