SSH项目
所有功能已经完美实现
其中有二个操作数据库方法addJack()//添加用户Jack
addLucy()//添加用户Lucy这两个方法必须具有事务性,也就是说,要么Jack和Lucy都添加到数据库,要么都不添加
这个功能也实现了,用的是spring的 声明式事务
[确实已经实现:当我已经添加Jack了,再添加Lucy时,我人为抛了个运行时异常
这时已经添加的Jack也会跟着回滚掉]现在突然来了一个要求
要求我判断Jack和Lucy的合法性,合法加,不合法不加[当然,只要有一个不合法,两个都是添加不进去的]
我为了不破坏原来的代码
使用了spring的'环绕通知'去拦截,拦截到不合法的参数时,我就不执行addJack(),或者不执行addLucy()现在有一个问题
加jack时,是合法的,拦截器放过去,jack也添加了
但是随后而来的lucy是非法的,拦截住了,没有执行addLucy()但是但是但是,刚刚进去的jack已经永远的进入数据库了,没有回滚掉!!我在想,可不可把拦截器也放到那一个事务里,当拦截器发现有非法参数
能不能得到当前事务的控制权,手动进行事务的回滚呢???望高手赐教!!!SSH版本: struts 1.X   spring 2.9  hibernate 3.2再次感谢!!!

解决方案 »

  1.   

    addJack()//添加用户Jack
    addLucy()//添加用户Lucy 
    你是针对于这两个方法建立的通知?这两个应该是一个业务吧,在一个声明式事务中,通知应该放在那个业务之前发起
      

  2.   

    对,应该将两add*()方法封装到一个方法中形成一具体业务,再对其进行事务管理
      

  3.   

    你好,
    我只能对每个方法建立通知,
    addJack(Jack jack)//添加用户Jack 
    addLucy(Lucy lucy)//添加用户Lucy 
    看实际的方法签名
    我在环绕通知里要得到每个方法进去的参数,然后单独判断啊
    因为不是说 要么参数都对 要么参数都不对
    有可能这个参数对 那个参数不对 也可能反过来 [我还得在页面说到底是jack不对还是lucy不对啊所以只好去拦截每个细致的方法
      

  4.   

    spring声明式事务,是自动提交和回滚的如果你的项目有特殊原因,那么就用特殊方法吧,比如在通知中抛出数据库异常
      

  5.   


    嗯,知心人啊!我设置的粒度细也有我的苦衷啊,
    我怕几分钟后,需求又有变化,说jack要判断的,lucy无所谓
    然后吃饭过后,领导又说,刚刚说错了,是lucy要判断的,jack无所谓的我设置的粒度细,我以后就不怕变化了,随便领导想判断哪个,
    我只要在 XML里把 环绕通知 设置到 具体的 JackDAO 或者 LucyDAO 上了就可以了谢谢landor2004,你说的方法我马上就试试看,
    但是我还是想再请教你一下:就是我刚刚说的"当拦截器[就是那个环绕通知]发现有非法参数 
    能不能得到当前事务的控制权,手动进行事务的回滚呢??? "
      

  6.   

    可以用编程方式回滚,但是spring的事务提交与会滚都是有framework自行完成的,所以如果你想编程方式回滚的话,就必须使用spring的api,与spring产生了耦合,这样就违背了pojo的本质,不太建议使用;
    回滚代码是:
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();spring建议开发者用抛出异常方式来完成回滚,这个异常必须是uncheck异常,或者在spring配置文件中配置所需要回滚的check异常;
      

  7.   

    再回Landor2004你说的方法可以把已经保存的JACK回滚出来 在通知中抛出数据库异常 ,可是程序也停了 ,页面也不动了我试着try catch 
    ........
    .......
    没有用 只要程序继续执行 保存的jack就回不来了,
    好象现在要让jack回滚,只好让程序死掉,看来在通知里还得拿到当前事务的控制权!手动回滚!
      

  8.   


    "这样就违背了pojo的本质" 这个我不同意
    我看啊,我是在'通知'里写的呀,就相当是一个插件,
    什么时候领导说,什么都不用检查了,我把那个'通知'去掉就可以[当然代码我是不动的,我只要在XML里把配置一改就可以了]
    什么时候领导说,要检查jack,那就设置到jackDAOImpl上
    什么时候领导说,要检查lucy,那就设置到lucyDAOImpl上
    什么时候领导说,统统的检查检查,那我就设置到 这个'包'上的add*方法上
    这样不是非常完美么原来的代码一点都没有污染啊
      

  9.   


    刚刚试了一下,
    报错,程序停止

    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    这个的确把当前事务设置为 回滚 的,
    但是从最后异常的堆栈上看,
    并没有阻止事务的提交也就说发生了这个错误是因为,
    事务提交了,但是我已经把事务设置为'回滚'的
    所以报错了
      

  10.   

    当然了
    rollback都出来了2009-08-11 10:18:43,609 DEBUG [org.hibernate.transaction.JDBCTransaction] - rollback
    2009-08-11 10:18:43,609 DEBUG [org.hibernate.transaction.JDBCTransaction] - rolled back JDBC Connection
    ......
    2009-08-11 10:18:43,625 DEBUG [org.hibernate.impl.SessionImpl] - closing session
    ......
    我的测试环境:spring2.5、hibernate3.3
    spring不会蠢的连这种简单的事情都做不了的,你仔细再看看吧,呵呵
      

  11.   

    哎,我脑子太笨了
    弄来弄去还是有
    Transaction is already completed - do not call commit or rollback more than once per transaction
    这个异常大侠的测试代码有没有删了啊如果没有删,大侠可否慷慨将代码打包 发送到 [email protected] [建议copy一下,收不到我会整个星期睡不好的 ]谢谢!
      

  12.   

    搞定了,还是要动用 尘封 已久的纸和笔,静下心来,理清思绪再次谢谢Landor2004I will remember u !