问题描述
用的是spring mvc和mybatis框架。数据库是mysql。然后发现事务配置了不起作用。。业务逻辑是新增用户,用户新增成功之后再在其他表插入一条对应的用户角色关联信息。现在问题是假如用户插入成功之后。。插入对应的用户角色关联信息出错后,用户那条新增记录不能自动删除。看了很多人说是因为@service提前扫描的问题。那个我改过了。还有说是表的引擎不是InnoDB。但是我们建的表是InnoDB。还有说要抛出RuntimeException。我也抛出了。。但是还是没用。没办法。请大家看下:-serlet.xml:<mvc:resources mapping="/resources/**" location="/resources/" /> <context:annotation-config /> <mvc:annotation-driven /> <!-- ①:对web包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能 --> <context:component-scan base-package="com.xuanyan.uebuycar.*"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" /> </context:component-scan><bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/> <!-- ②:启动Spring MVC的注解功能,完成请求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="cacheSeconds" value="0" /> <property name="webBindingInitializer"> <bean class="com.xuanyan.uebuycar.admin.util.WebDataBinder4DateAndTime"/> </property> </bean> <!-- ③:对模型视图名称的解析,即在模型视图名称添加前后缀 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/" p:suffix=".html"/> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource" p:basename="i18n/messages"/> applicationContext.xml:<!-- 用于持有ApplicationContext,可以使用SpringContextHolder.getBean('xxxx')的静态方法得到spring bean对象 --><bean class="com.xuanyan.uebuycar.admin.util.SpringContextHolder" lazy-init="false" /><!-- define the SqlSessionFactory --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="proxool" /><property name="configLocation" value="classpath:mybatis-config.xml" /></bean><!-- 数据连接事务 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="proxool" /></bean> <!-- 不扫描带有@Controller注解的类。因为这些类已经随容器启动时,在servlet-context中扫描过一遍了 --> <context:component-scan base-package="com.xuanyan.uebuycar"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan> <!-- 激活annotation功能 --><context:annotation-config /><!-- 激活annotation功能 --><context:spring-configured/><!-- mybatis接口 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.xuanyan.uebuycar.admin.dao" /></bean><!-- 连接事务的注解配置 --> <tx:annotation-driven transaction-manager="transactionManager" /> <aop:config proxy-target-class="true"><aop:pointcut id="fooServiceOperation"expression="execution(* com.xuanyan.uebuycar.admin.service..*.*(..))" /><aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation" /></aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"><!-- the transactional semantics... --><tx:attributes><tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception" /> <tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/></tx:attributes></tx:advice>方法:public String addOrUpdate(SysUser record,SysUser currUser,String actionType,String roleId){String str=getDefJsonString(false, "操作失败,请稍后再试!");try {if(record!=null){Date now=new Date();SysUserExample example=new SysUserExample();example.createCriteria().andUserCodeEqualTo(record.getUserCode());List<SysUser> list=sysUserMapper.selectByExample(example);if("add".equalsIgnoreCase(actionType)){if(list!=null&&list.size()>0){str=getDefJsonString(false, "操作失败,该账号已存在!");return str;}String userId=CommonUtil.getUUIDString();record.setUserId(userId);record.setUserPassword(CommonUtil.getMD5Str(SystemCommonParam.DEFAULT_USER_PWD));record.setUpdateUser(currUser.getUserCode());record.setUpdateTime(now);if(sysUserMapper.insertSelective(record)>0){SysRoleUser ru=new SysRoleUser();//ru.setRoleUserId(CommonUtil.getUUIDString());ru.setRoleId(roleId);ru.setUserId(userId);ru.setUpdateUser(currUser.getUserCode());ru.setUpdateTime(now);if(sysRoleUserMapper.insertSelective(ru)>0){str=getDefJsonString(true, "新增成功!");}}}else if("edit".equalsIgnoreCase(actionType)){if(list!=null&&list.size()>0){if(!list.get(0).getUserId().equals(record.getUserId())){str=getDefJsonString(false, "操作失败,该账号已存在!");return str;}}record.setUpdateUser(currUser.getUserCode());record.setUpdateTime(now);if(sysUserMapper.updateByPrimaryKeySelective(record)>0){SysRoleUser ru=new SysRoleUser();ru.setRoleId(roleId);SysRoleUserExample ex=new SysRoleUserExample();ex.createCriteria().andUserIdEqualTo(record.getUserId());if(sysRoleUserMapper.updateByExampleSelective(ru, ex)>0){str=getDefJsonString(true, "修改成功!");}}}}} catch (Exception e) {str=getDefErrorString();e.printStackTrace();throw new RuntimeException();}return str;}类路径:com.xuanyan.uebuycar.admin.services.sys.SysUserService希望各位有知道能够告知一下。。是不是我service方法写的不对?
解决方案
<aop:pointcut id="fooServiceOperation" expression="execution(* com.xuanyan.uebuycar.admin.service..*.*(..))" /> com.xuanyan.uebuycar.admin.services.sys.SysUserService 1、先在控制器中通过AopUtils.isAopProxy 看看你注入的是不是代理对象 再来分析
解决方案二:
1、mysql存储引擎要为innodb2、方法不用try catch,或者catch的异常为RunException或者DataAccessException,因为为exception的时候,异常没法捕获满足以上两点,相信你的问题就解决了!!!