一直对着个问题不是很确定,现在正好有时间测试下:
1、环境:
1、springMVC,Hibernate,maven3
spring版本
<spring-version>3.1.1.RELEASE</spring-version>
hibernate的jar
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.3.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.4.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>ejb3-persistence</artifactId>
<version>1.0.2.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.1.0.GA</version>
</dependency>
2、数据库:mysql-5.6.26( innodb)
2、spring配置:
jdbcTemplate和hibernateTemplate配置同一个数据源
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate/hibernate.cfg.xml</value>
</property>
<property name="dataSource" ref="dataSource"></property>
<property name="packagesToScan">
<list>
<value>com.**.po</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${db.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
</props>
</property>
</bean>
<!-- JDBC模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Hibernate模板 -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置事务的传播特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
<tx:method name="update*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
<tx:method name="delete*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
<tx:method name="business*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- -->
<aop:config>
<aop:pointcut id="allServiceMethod" expression="execution(* com..service..*.*(..))" />
<aop:advisor pointcut-ref="allServiceMethod" advice-ref="txAdvice" />
</aop:config>
防止重复扫描包导致事务配置无效:
父容器配置:
<!-- 父容器扫描除controller外的所有注解 -->
<context:component-scan base-package="com.yang.platform">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
springMVC子容器:
<!-- springMVC servlet 只扫描controller -->
<context:component-scan base-package="com.yang.platform.controller">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
3、测试:
1、service实现类的方法:
@Override
public boolean savePerson(Object o) {
// TODO Auto-generated method stub
/**
* 两句插入sql 分别用JdbcTemplate和HibernateTemplate执行
*/
String sql1 = "insert into person(name,address,age,gender,tel)values('yang','海淀区',20,'女','010-111111')";
String sql = "insert into person(name,address,age,gender,tel)values('zhang','丰台区',25,'男','010-111111')";
/**
* 调用hibernate执行sql
*/
getBaseDao().execute(sql);
/**
* 调用jdbctemplate执行sql
*/
getBaseDao().getJdbcTemplate().execute(sql1);
getLogger().info(sql);
getLogger().info(sql1);
/**
* 抛出nullpointer异常 导致回滚
*/
String nullStr = null;
return nullStr.equals("");
}
2、dao层的方法:
@Override
public int execute(final String sql) {
// TODO Auto-generated method stub
return getHibernateTemplate().execute(new HibernateCallback<Integer>() {
@Override
public Integer doInHibernate(Session session)
throws HibernateException, SQLException {
// TODO Auto-generated method stub
int r = -1;
r = session.createSQLQuery(sql).executeUpdate();
session.close();
return r;
}
});
}
3、controller代码
@RequestMapping("test/test.do")
public void test(HttpServletRequest request, HttpServletResponse response) {
PrintWriter out = null;
try {
out = response.getWriter();
out.print(testService.savePerson(1));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
结果:调用controller之后,数据库表中两条记录都没有insert。