开发使用的是ssh,action调用service,service调用dao。使用spring的事务管理将事务开启在service层,但是现在有个疑问。如果我的action调用了多个service那个如果其中一个service出现异常这个service会回滚但是对于整个action来说其实还是不对的。那么事务就要开启在action层了。那么如果我的action经常要调用多个service还有必要要把事务开启在service层吗?下面是伪代码
[code="java"]
class testAction{
testAService.add();
testBService.update(); //出现异常,那么add已经调用过了是不会回滚事务的!!!
testCService.del()
}
[/code]
虽然我可以在action层开启事务,这样这3个service就会在同一个事务中了。
不好意思,直接copy你的代码了,在service层这么写
[code="java"] @Transactional
class someOperation{
try{
add();
}catch(Exception e){
...
}
try{
update();
}catch(Exception e){
...
}
try{
del();
}catch(Exception e){
...
}
} [/code]
不需要在action开启事务,你想要保证add,update,del的原子性,就要在service层把他们放在一个事务里面执行。
Action当然不应该放置业务逻辑和事务控制,在很多的框架中,Controller依赖Servlet API,这样非HTTP请求不就能复用业务逻辑和事务控制。
要考虑你的Service的粒度设计,可能许多人会将service中的内容当做dao来写,而将Action当做了Service。
在Action中调用了多个service的业务逻辑方法相当于在Action中编写业务逻辑代码,从分层的角度讲,Action应该做的只是数据的获取,执行某个动作,视图的转发,而动作的具体分解交由service完成。所以还是应该将Action中的调用三个service类业务逻辑类的方式封装到一个service中完成。
除非你的业务足够的复杂,非要这么做才能实现,否则不应该将事务控制在Action。
[quote]也就是说我要在testAService的add()方法中调用testBService的update方法和testCService的del方法是吗??[/quote
不必要在add中调用另外两个方法才能达到效果,可以这样
[code="java"]
@Transactional
class testAction{
try{
testAService.add();
}catch(Exception e){
...
}
try{
testBService.update();
}catch(Exception e){
...
}
try{
testCService.del();
}catch(Exception e){
...
}
}
[/code]
[quote]这样写是将事务开启在action吗?? [/quote]
当然不是开启在action,testAction只是一个方法的名称
事务不该开启在action层,@xiaofengxp说的有道理。涉及到一些业务逻辑的要放在service层,也就是这个方法应该放在某个service里面
我认为事务是肯定要在service层控制的,如果使用的是spring配置事务,那么需要抛出异常(默认是运行时异常)才能触发回滚。而action通常要捕获异常并作处理的,比如出现异常要跳转到特定的地方去。
但是我的回答附加一个疑问,希望大家帮忙解惑。就是当有很多业务校验并最终有业务操作的时候,这些校验和业务操作是否都放在(或嵌套进)一个service中以保证他们存在一个事务中呢?
我遇到的问题是,在action中顺序排放很多service方法用于各种校验,顺序通过后将会进入业务操作的service,但是我怀疑出现并发的时候,在校验之后且业务操作之前,可能有其他部分对数据有操作。然后当前的业务操作将对脏数据进行处理。
我不知道我说的对不对?该怎么设计action中的service方法?