application.xml代码
<bean id="transactionAttributeSource" class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
<property name="properties">
<props>
<prop key="*">PROPAGATION_REQUIRED,-DaoAccessException</prop>
<prop key="get*">PROPAGATION_REQUIRED,ISOLATION_READ_UNCOMMITTED,readOnly</prop>
</props>
</property>
</bean>
DaoAccessException.java代码
public class DaoAccessException extends RuntimeException{
public DaoAccessException(Throwable rooCase){
super(rooCase);
}
public DaoAccessException(String msg){
super(msg);
}
public DaoAccessException(String msg,Throwable rooCase){
super(msg,rooCase);
}
}
UserDaoImpl.java代码
public class UserDaoImpl extends HibernateDaoSupport implements UserDao{
public void addUser(Object o)throws DaoAccessException{
try {
getHibernateTemplate().save(o);
throw new DaoAccessException("回滚");
} catch (Exception e) {
// TODO: handle exception
throw new DaoAccessException(e);
}
}
}
测试代码
@org.junit.Test
public void addUser() {
ApplicationContext context = new FileSystemXmlApplicationContext(
"D:\\MyEclipse 5.5.1 GA\\workspace\\SpringAndHibernate\\WebRoot\\WEB-INF\\applicationContext.xml");
UserDao userDao = (UserDao) context.getBean("userDao");
User user = new User();
user.setName("赵六");
try {
userDao.addUser(user);
} catch (DaoAccessException e) {
// TODO: handle exception
e.printStackTrace();
}
}
设想中的效果是当程序执行完毕后 这个添加用户的事务操作应该回滚 可实际上却写进了数据库 这是为什么?
你现在用的transactionInterceptor在你执行完userDao.addUser(user);后自动提交
因为你把事务其实就是拦截器拦截在Dao层了
userDAO
transactionInterceptor
这里。
你应该把这里的dao换成service
然后在service里调用dao的方法。。。。。。。
UserService.java
....
public int addUser(User user){
userDao.addUser(user);
}
....
userService //注意这里,不要切在dao上,应该切在service
transactionInterceptor
你的bean配置没有配置吧,就是target,你的植入事务的实现类呢?
没有抛出异常怎么回滚呢?
使用SpringTest提供的AbstractTransactionalDataSourceSpringContextTests类,然后配置rollback为true
public abstract class BaseManagerTestCase extends
AbstractTransactionalDataSourceSpringContextTests {
// ~ Static fields/initializers
// =============================================
protected final Log log = LogFactory.getLog(getClass());
protected static ResourceBundle rb = null;
protected String[] getConfigLocations() {
setAutowireMode(AUTOWIRE_BY_NAME);
setDefaultRollback(true);
return new String[] { "classpath*:/applicationContext*.xml" };
}
}
在2.0 和2.5中尽量还是用aop还做吧
反正我是的
<aop:config>
<aop:pointcut id="managersMethod"
expression="execution(* cbcbccbcb.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="managersMethod" />
</aop:config>
比较方便
try {
userDao.addUser(user); //这句的下面没有抛异常,怎么会rollback呢
} catch (DaoAccessException e) {
// TODO: handle exception
e.printStackTrace();
}
这里涉及到事务的问题,也就是transaction
你仔细看看事务吧
我提供个大概思路
你应该建立个service层,由service调用dao层,再将aop切入到service上
也就是说
你现在的切入法是在dao层每个调用持久层方法后直接提交
就是这里:
userDAO
transactionInterceptor
但应该是
你在service做完一系列的数据库操作后再提交
只要有一个数据库操作出错就需要回滚
也就是将transactionInterceptor切入到service上