xcc258
2013-04-06 18:41
浏览 447
已采纳

spring mvc+mybatis 事务控制不起作用

用的是spring mvc和mybatis框架。数据库是mysql。然后发现事务配置了不起作用。。业务逻辑是新增用户,用户新增成功之后再在其他表插入一条对应的用户角色关联信息。现在问题是假如用户插入成功之后。。插入对应的用户角色关联信息出错后,用户那条新增记录不能自动删除。看了很多人说是因为@service提前扫描的问题。那个我改过了。还有说是表的引擎不是InnoDB。但是我们建的表是InnoDB。还有说要抛出RuntimeException。我也抛出了。。但是还是没用。没办法。请大家看下:

-serlet.xml:
[code="xml"]

<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"/>   

[/code]

applicationContext.xml:
[code="xml"]

<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>

[/code]

方法:
[code="java"]
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 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;
}

[/code]

类路径:com.xuanyan.uebuycar.admin.services.sys.SysUserService

希望各位有知道能够告知一下。。是不是我service方法写的不对?

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • jinnianshilongnian 2013-04-06 21:37
    已采纳

    expression="execution(* com.xuanyan.uebuycar.admin.service..*.*(..))" />

    com.xuanyan.uebuycar.admin.[color=red]services[/color].sys.SysUserService

    1、先在控制器中通过AopUtils.isAopProxy 看看你注入的是不是代理对象 再来分析

    打赏 评论
  • songf_software 2013-04-06 23:33

    1、mysql存储引擎要为innodb
    2、方法不用try catch,或者catch的异常为RunException或者DataAccessException,因为为exception的时候,异常没法捕获
    满足以上两点,相信你的问题就解决了!!!

    打赏 评论

相关推荐 更多相似问题