注释 Propagation.NEVER 不起作用
The annotation Propagation.NEVER doesn't work
程序员!我不明白 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>
服务class:
@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
为什么不起作用?
谢谢:)
Spring中的事务是基于代理的:当一个bean A调用一个事务bean B时,它实际上调用了一个动态代理的方法,它处理事务的开启,然后委托给实际bean B,然后处理事务的commit/rollback。
如果您从单个 bean A 的 method1 调用 method2,您的调用将不再被事务代理拦截,因此 Spring 完全不知道 method2() 已被调用。所以没有什么可以检查没有交易。
将方法 2 放入 另一个 bean 中,注入 BookManager,一切都会按预期工作。
程序员!我不明白 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>
服务class:
@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
为什么不起作用?
谢谢:)
Spring中的事务是基于代理的:当一个bean A调用一个事务bean B时,它实际上调用了一个动态代理的方法,它处理事务的开启,然后委托给实际bean B,然后处理事务的commit/rollback。
如果您从单个 bean A 的 method1 调用 method2,您的调用将不再被事务代理拦截,因此 Spring 完全不知道 method2() 已被调用。所以没有什么可以检查没有交易。
将方法 2 放入 另一个 bean 中,注入 BookManager,一切都会按预期工作。