我正在尝试实现一个服务方法的“只读”事务,遵循Spring Framework Reference的11.5.2项,但事务仍自动将数据提交到数据库。我使用的是Spring 3.1.0.RELEASE、Hibernate 3.5.5-Final和Oracle 11g Express Edition Release 11.2.0.2.0。以下是我的设置:
关于建议、切入点、顾问和事务管理器的XML:
调用
关于建议、切入点、顾问和事务管理器的XML:
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="myServiceMethods" expression="execution(* my.example.service.*.*(..))" />
<aop:advisor pointcut-ref="myServiceMethods" advice-ref="transactionAdvice" />
</aop:config>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<!-- the sessionFactory bean declaration does not set the -->
<!-- hibernate.connection.autocommit property as either true or false -->
</bean>
服务接口:
package my.example.service;
public interface MyService {
void getFoo();
void bar();
}
服务实现:
package my.example.service.impl;
import my.example.dao.MyDao;
import my.example.domain.MyEntity;
import my.example.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MyServiceImpl implements MyService {
@Autowired
private MyDao dao;
public void getFoo() {
MyEntity example = this.dao.getMyEntity(1L);
example.setSomeInteger(2);
example.setSomeString("three");
}
public void bar() {
MyEntity example = this.dao.getMyEntity(4L);
example.setSomeInteger(5);
example.setSomeString("six");
}
}
调用
getFoo()
或 bar()
后,数据库将被更新,即使 getFoo()
被标记为只读。但如果我更改这两行代码:<tx:method name="get*" read-only="true" />
<tx:method name="*"/>
到:
<tx:method name="*" read-only="true" />
这两种方法都尊重read-only
属性,并且数据不会提交到数据库。
发生了什么?我做错了什么?我错过了什么?
<tx:annoation-driven/>
并将@Transactional(readOnly = true)
添加到单个方法中,则会被<tx:method name="*"/>
忽略/覆盖。数据仍然被提交。 - boobsbr<tx:annotation-driven/>
,并在单个方法上注释@Transactional
和@Transactional(readOnly=true)
可以工作,如果在只读
方法内部没有调用SessionFactory.getCurrentSession().saveOrUpdate(myEntityInstance)
。如果在只读
方法内部调用saveOrUpdate()
,不会抛出任何异常。 - boobsbr