本帖最后由 yuandaobo 于 2013-03-11 09:22:01 编辑

解决方案 »

  1.   


    try {
                    order = this.orderBiz.addNewOrder(buyCount, client);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
    //这里怎么没有实物回滚语句呢?XXX.rollback();
                    e.printStackTrace();
                }
      

  2.   

    你捕获了异常,所有回滚不了的,要么去掉try,要么在catch里加TransactionAspectSupport.currentTransactionStatus().setRollbackOnly ;
      

  3.   

    这个代码是Action里面的,需要在这里加吗?还有xxx能不能说下是什么、以前没有手动写过事务回滚
      

  4.   

    我加了以后,还是一样,还请指教,下面是Action修改后的代码:
    try {
    order = this.orderBiz.addNewOrder(buyCount, client);
    } catch (Exception e) {
    // TODO Auto-generated catch block
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    e.printStackTrace();
    }
      

  5.   

    dao没有捕获,直接抛出Exception的,dao层代码如下
    public void add(Object ogj) throws Exception{
    super.getHibernateTemplate().getSessionFactory().getCurrentSession().save(ogj);
    }
      

  6.   

    看看前后是否是一个事物,是的话在catch里写代码会滚吧
      

  7.   

    回滚代码是在biz层写呢,还是在Action层?还请明示
      

  8.   

    哪个层应该没关系的,spring界定事务属性与哪个层无关吧就看事务边界界定了没,现在通过add*,还有按理应该自动回滚的吧?没有自动回滚肯定有原因存在,找到原因而不是直接手动回滚
      

  9.   

    <aop:pointcut id="allManagerMethod" expression="execution (* com.cloudsoar3c.biz.*.*(..))"/>
    试试改成这样行不行.
    expression="execution (* com.cloudsoar3c.biz.*.*(..))"/>
    第一个*代表的是返回值;第二个*表示的是biz下面的子包;第三个*表示的是方法名称;(..)表示的是方法参数.
    试试看!!
      

  10.   

    不知道你用的什么数据库,mysql?看下数据库是什么引擎的?如果不是innerdb,就不能自动提交事务。在
    hibernate配置文件里加上<property name="connection.autocommit">false</property>
      

  11.   

    多谢你的回复,我改了以后,还是这样,下面是我修改后的代码
    <aop:pointcut id="allManagerMethod" expression="execution (* com.cloudsoar3c.biz.*.*(..))"/>
      

  12.   


    数据库用的mysql,刚才使用命令show variables like 'table_type';查看表类型是:MyISAM
    然后我添加了<property name="connection.autocommit">false</property>问题仍然存在
      

  13.   

    现在如果我在biz层的方法中,直接添加一个throw new RuntimeException("");,事务就会回滚,代码如下:
    public TOrder addNewOrder(Integer buyCount, TClient client){
    TServerHostLicense serverHostLicense = new TServerHostLicense();
    serverHostLicense.setHostId(System.currentTimeMillis()+"");
    serverHostLicense.setAddTime(new Date());
    serverHostLicense.setHostName("测试主机名");
    serverHostLicense.setLicenseFile("licenseFile........");
    serverHostLicense.setStatus(-1);
    serverHostLicense.setSupportClientCount(buyCount);
    serverHostLicense.setTClient(client);
    //添加主机服务器信息
    //boolean addResult = this.serverHostLicenseDao.add(serverHostLicense);
    this.serverHostLicenseDao.add(serverHostLicense);
    //TLicensePrice licensePrice = getPriceByBuyCount(buyCount);//获取单价
    TOrder order = new TOrder();
    //生成订单ID
    //String orderId = this.utilBiz.getUUID(Attribute.UUID_ORDER);
    order.setOrderId("1362726845687907");//此处ID故意重复,让其出错
    order.setBuyCount(buyCount);
    order.setOrderTime(new Date());
    order.setPreferentialPrice(0);//默认优惠价格为0
    //order.setPrice(licensePrice.getPrice());
    order.setPrice("111");
    order.setStatus(Attribute.ORDER_STATE_DFK);//初始化状态为待付款状态
    order.setTClient(client);
    order.setTServerHostLicense(serverHostLicense);
    //order.setTotalPrice((Integer.parseInt(licensePrice.getPrice())*buyCount+""));
    order.setTotalPrice("2222");
    this.orderDao.addOrder(order);//添加新增订单到数据库中
    if(1==1){
    throw new RuntimeException("");
    }
    return order;
    }
      

  14.   

    默认的配置中,spring框架的事务设施代码仅仅标记运行时非检查异常来设置回滚标记,也就是说当抛RuntimeException实例或子类时。在默认的配置中,如果检查性异常被抛出是不会引起事务回滚的。
    下面的代码片段说明了怎么给应用程序指定的checked异常回滚操作
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
    <tx:method name="get*" read-only="true" rollback-for="NoProductInStockException"/>
    <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    同样,可以指定某种异常不用回滚
    <tx:advice id="txAdvice">
        <tx:attributes>
    <tx:method name="updateStock" no-rollback-for="InstrumentNotFoundException"/>
    <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
      

  15.   

    那就是说,如果我在dao和biz层都不异常作处理(也就是即不抛出异常,也不捕获异常),是不是就可通过spring来管理事务的回滚和提交了呢,你提到的这些,我有尝试着改过,不知道是哪里出现了问题,就是在biz层中数据库操作异常后,仍然不能回滚事务
      

  16.   

    <!--配置事务  -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    <!-- 配置通知 -->
    <tx:advice id="txAdvice">
    <tx:attributes>
    <tx:method name="find*" read-only="true"/>
    <tx:method name="*"/>
    </tx:attributes>
    </tx:advice>
    <!-- 配置通知器 -->
    <aop:config>
    <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.svse.service.*Service.*(..))"/>
    </aop:config>
      

  17.   

    spring事务管理默认回滚条件是runtimeexcetion,楼主想通过手动抛出异常来回滚的话,可以指定回滚条件
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
    <tx:method name="*" rollback-for="java.lang.Exception"/>
    <tx:method name="doGet*" read-only="true"/>
    </tx:attributes>
    </tx:advice>
      

  18.   

    按照我老大的说法,你配置语句里面tx:annotation-driven 这句话,不用,这是生命用注解吧,你删了试试..
    如果你切入点没配错的话,照理说dao,service一直上抛应该是可以回滚的...我也不懂,在学..
      

  19.   

    你可以自己封装个单一事物的方法,反正我真的不喜欢spring
      

  20.   

    这位兄弟的提示很对(还有12楼兄弟),我也没看出来哪里配置有问题,并且我也没有对异常进行捕获,最后一看,我的MySql数据库表引警为MyISAM,在google一下,说这种引警不支持事务,只有InnoDB类型才支持,我修改了数据库中需要进行事务处理的表的引擎,再测试发现,事务成功回滚(心里总算是踏实了),后来我又想着试试如果我捕获异常,会不会有问题,我在DAO层和BIZ层都捕获取异常,并且捕获异常后,也没有另外处理(TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();),发现事务依然可以成功回滚、所以我认为捕获异常应该不会对事务回滚造成影响,可是在网上好多人认为有影响的,不知道是我测试哪里有问题还是怎么了,如果哪位仁兄知道,请不吝赐教、