以前做过的一个spring mvc框架的配置,最开始的时候全部是xml配置,事务管理没有问题,用的是拦截器那种。现在修改框架,为了使用方便,修改了配置文件,发现事物管理不好用了,求大神赐教。
我输出注入action的service,看到控制台的信息不是代理类的信息,是service本身类信息(LoginServiceImpl@19b4c30)。说明,事务没有加入到service。
也不想全部使用annonation,这样开发的时候,还需要给类或者方法追加annonation标记。
xml如下:applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd "> <context:property-placeholder location="classpath:properties/jdbc.properties"/> <!-- データソース --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.userName}" p:password="${jdbc.password}" p:maxActive="100" p:maxIdle="30" p:maxWait="500" p:defaultAutoCommit="false"/> <!-- トランザクション マネジャー --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="del*, delete*" propagation="REQUIRED" read-only="false" isolation="READ_COMMITTED" rollback-for="Exception"/> <tx:method name="upd*, update*" propagation="REQUIRED" read-only="false" isolation="READ_COMMITTED" rollback-for="Exception"/> <tx:method name="ins*, insert*" propagation="REQUIRED" read-only="false" isolation="READ_COMMITTED" rollback-for="java.lang.RuntimeException"/> <tx:method name="find*, get*, select*" propagation="SUPPORTS" isolation="READ_COMMITTED"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="serviceMethod" expression="execution(* app.*.service..*(..))"/> <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice"/> </aop:config> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="dataSource" p:configLocation="classpath:common/mybatis/config/mybatisConfig.xml" p:mapperLocations="classpath:common/mybatis/xml/*.xml" p:typeAliasesPackage="common.mybatis.entity"/> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" p:basePackage="common.mybatis.dao"/> <context:component-scan base-package="app"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> </beans>
在DispatcherServlet的启动文件里面
<context:component-scan base-package="app"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" /> </context:component-scan>
注入action的service肯定是applicationContext.xml里面。
package结构如下
/src/app/login/service/LoginService.java
/src/app/login/service/impl/LoginServiceImpl.java
package app.login.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import app.login.service.LoginService; import common.mybatis.dao.TestMapper; import common.mybatis.entity.Test; @Service @Transactional public class LoginServiceImpl implements LoginService { @Autowired private TestMapper testMapper; @Override public int insertA() throws Exception { System.out.println(); System.out.println(testMapper); Test record = new Test(); record.setUserName("01"); record.setPassword("01"); testMapper.insert(record); if (1 == 1) { throw new RuntimeException(); } record = new Test(); record.setUserName("02"); record.setPassword("02"); testMapper.insert(record); return 0; } }
我测试的时候
第一次
testMapper.insert(record);
执行 以后db就有已经插入数据了。
抛出异常后没有回滚
--2013/4/26已解决
配置切面的时候:
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="del*, delete*" propagation="REQUIRED" read-only="false" isolation="READ_COMMITTED" rollback-for="Exception"/> <tx:method name="upd*, update*" propagation="REQUIRED" read-only="false" isolation="READ_COMMITTED" rollback-for="Exception"/> <tx:method name="ins*, insert*" propagation="REQUIRED" read-only="false" isolation="READ_COMMITTED" rollback-for="java.lang.RuntimeException"/> <tx:method name="find*, get*, select*" propagation="SUPPORTS" isolation="READ_COMMITTED"/> </tx:attributes> </tx:advice>
name中不能用逗号
<tx:method name="del*, delete*" propagation="REQUIRED" read-only="false" isolation="READ_COMMITTED" rollback-for="Exception"/>