`
sgp2004
  • 浏览: 20390 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

action可否直接使用spring的声明式事务?

    博客分类:
  • ssh
阅读更多
由于图省事,而且系统比较小,感觉service层比较繁琐,就直接在action里调用的dao
现在想使用事务 action代码大致如下
public ActionForward addOrg(
orginfoDAO.insert(orginfo);
userDAO.insert(userInfo);
}


action里有这样的两个操作,分别用两个dao去处理,我想加上事务处理,使用的spring配置好像还是1.X的(见笑)
使用HibernateTransactionManager 和TransactionProxyFactoryBean类去管理事务,在target里设置target为action的bean name
    
  <bean id="transactionManager"   
       class="org.springframework.orm.hibernate3.HibernateTransactionManager">
      <bean id="orgManagerProxy" lazy-init="true"   
         class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager"><ref bean="transactionManager"/>
            </property>
            <property name="transactionAttributes">
                <props>
                    <prop key="insert*">PROPAGATION_REQUIRED,-Exception</prop>
                    <prop  
                    key="add*">PROPAGATION_REQUIRED,Exception</prop>                      
                    <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
                </props>
            </property>
             <property name="target">    
	             <ref="/userOrgManager">
            </property> 
       </bean>  

action bean定义如下
 <bean  name="/userOrgManager"
	           class="web.manager.ManagerAction">
	           <property name="baseDAO">
	             <ref local="baseDAO"/>
	           </property>
	           <property name="userDAO">
	             <ref local="userDAO"/>
	           </property> 
	           <property name="orginfoDAO">
	             <ref local="orginfoDAO"/>
	           </property>         
	    </bean>  


但是这样配置是不生效的,直接使用TransactionProxyFactoryBean去管理dao的话,只能是单个dao进入事务管理,比较郁闷,如果有service层的话,可以用action去调用包装好的带事务的service,但现在这样配置后使用action依然是没有包装过的原始action,不知道怎么配比较好,还是非得加service层呢?希望大家指教。我用编程式事务去管理是可以的,但是比较麻烦,想用直接注入实现一下。
分享到:
评论
28 楼 sgp2004 2009-01-05  
chen-516888 写道
你对execute()进行事务配置才有效果的
如果pointcut选择了DAO类的方法肯定有问题啊
因为生成的代理是自定义的Action Bean 的代理
自然是对Action Bean 的方法进行拦截和事务开启和关闭的吧
呵呵
个人拙见

我就是选择了 Action的方法无效才进来问的 呵呵 继续研究中。。。
27 楼 sgp2004 2009-01-05  
chen-516888 写道
使用spring管理Action Bean的配置方式
将Action Bean在Spring IoC容器中进行注册,则可以对Action Bean进行声明式事务管理了吧?
配置事务的原子方法应该是execute()吧........



我用的是dispatchAction 所以没有excute方法 而且光管理excute方法的话估计也是无效的
因为真实操作是在baseDAO 反正使用通配符“*”就限制住了 呵呵 
26 楼 volking 2009-01-03  
楼主,能用了吗?能用就发个例子给我瞧下,我懒得写的。
jar文件写个“名字-版本”就行了,其他的发给我。
volking@yahoo.cn
25 楼 sgp2004 2008-12-30  
sdh5724 写道
如果项目复杂, 就不要在action里玩, 最好使用独立的业务类。 在业务类里面做事务。 简单的话就无所谓了, 你要在jsp上做事务也行。 没有一条解决问题的万能之路, 只是适合业务的需求而已!


嗯 谢谢指点 呵呵 因为是第一次做ssh的应用 以前是纯struts 然后加个business类就完了 所以对业务层的配置不是很熟 感觉有点复杂,而且业务其实比较简单 只有录入数据,上报和统计分析 初始需求只是一个表格履历 做一点算一点的 唉 也比较郁闷 很多需求他们都不说清楚
24 楼 sgp2004 2008-12-30  
yangke_love 写道
sgp2004 写道
daquan198163 写道
sgp2004 写道
daquan198163 写道

我猜测原因是ManagerAction的基类导致的,因为框架不是直接调用ManagerAction的方法,而是同意调用Action基类的入口方法(例如handleRequest),然后反射调用你的具体方法,因此你需要为这个入口方法指定事务属性简单办法就是用通配符把所以方法都包括进去:transactionAttributes设为&lt;prop key="*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;

嗯 可以了 嘿嘿 谢谢大哥了!
我的action的基类是dispatchAction 入口方法就不知道怎么指定了,应该是没限制到我action调用的BaseDao的方法,BaseDAO里的方法名是update,save之类的,可能没包含在匹配符号里边 现在只用 “*” 号就可以了 呵呵
还是我自己研究的不深入啊

红色的这部分我没看明白,你好像对Spring AOP事务拦截机制理解有误啊
因为就算配置对了也不可能控制DAO里的方法的,
因为AOP只能拦截到目标对象(这里是action)的方法

那到底是怎么回滚的呢? 我action里的方法addOrg 调用的是dao的delete()和insert()方法,而那两种方法都是通过hibernateTemplate去处理的,每个操作都是个事务,默认是自动提交事务的

请问这位兄弟你的Action 是不是用的Strut1的DispatchAction类
如果是这样的话,那么你没有事务支持是很正常的!
daquan198163 这个兄弟讲行很对,我也正是碰到了同样的情况,但是有一条
如果你简单的像他说的好样配的话,那就所有的其它方法的事务声明都没有实际的效果,
因为你实际上所有的方法调用都只是调用handleRequest方法,再在handleRequest方法中用反射的方式调用实际的业务时,实际方法(像update、save)并没有被拦截,而是拦截的handleRequest方法,那么对于update\save配置的信息就会失效!
有一种方法实出你的想法
你看看关于ActionDispatcher的用法,将handleRequest方法内部的反身代码移到新的类中去。


public class ActionAdatper extends Action {

	protected ActionDispatcher dispatcher ;
	
	protected Action action;
	
	@Override
	public void setServlet(ActionServlet servlet) {
		super.setServlet(servlet);
		this.action.setServlet(servlet);
	}
	public ActionAdatper(Action action){
		action.setServlet(servlet);
		dispatcher = new ActionDispatcher(action,ActionDispatcher.DISPATCH_FLAVOR);
	}
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return dispatcher.execute(mapping, form, request, response);
	}
}



public class NewerDelegatingRequestProcessor extends DelegatingRequestProcessor {
	
	protected Action getDelegateAction(ActionMapping mapping) throws BeansException {
		Action action=super.getDelegateAction(mapping);
		if(action==null){
			return null;
		}
		return new ActionAdatper(action);
	}
	

}


@Transactional(readOnly=false)
public class XXXXAction extends Action {

	/**
	 *
	 * 新增页面初始化处理
	 *
	 */
	public ActionForward create(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
		
	}
	
	
	/**
	 * 修改页面初始化处理
	 * 
	 */
	public ActionForward edit(ActionMapping mapping, ActionForm form,  HttpServletRequest request, HttpServletResponse response) {
		
          }
}



嗯 对 用的是struts1的东西 不过我照daquan大哥给的方法
transactionAttributes设为&lt;prop key="*"&gt;PROPAGATION_REQUIRED
这样就可以了
23 楼 sdh5724 2008-12-30  
如果项目复杂, 就不要在action里玩, 最好使用独立的业务类。 在业务类里面做事务。 简单的话就无所谓了, 你要在jsp上做事务也行。 没有一条解决问题的万能之路, 只是适合业务的需求而已!
22 楼 yangke_love 2008-12-30  
sgp2004 写道
daquan198163 写道
sgp2004 写道
daquan198163 写道

我猜测原因是ManagerAction的基类导致的,因为框架不是直接调用ManagerAction的方法,而是同意调用Action基类的入口方法(例如handleRequest),然后反射调用你的具体方法,因此你需要为这个入口方法指定事务属性简单办法就是用通配符把所以方法都包括进去:transactionAttributes设为&lt;prop key="*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;

嗯 可以了 嘿嘿 谢谢大哥了!
我的action的基类是dispatchAction 入口方法就不知道怎么指定了,应该是没限制到我action调用的BaseDao的方法,BaseDAO里的方法名是update,save之类的,可能没包含在匹配符号里边 现在只用 “*” 号就可以了 呵呵
还是我自己研究的不深入啊

红色的这部分我没看明白,你好像对Spring AOP事务拦截机制理解有误啊
因为就算配置对了也不可能控制DAO里的方法的,
因为AOP只能拦截到目标对象(这里是action)的方法

那到底是怎么回滚的呢? 我action里的方法addOrg 调用的是dao的delete()和insert()方法,而那两种方法都是通过hibernateTemplate去处理的,每个操作都是个事务,默认是自动提交事务的

请问这位兄弟你的Action 是不是用的Strut1的DispatchAction类
如果是这样的话,那么你没有事务支持是很正常的!
daquan198163 这个兄弟讲行很对,我也正是碰到了同样的情况,但是有一条
如果你简单的像他说的好样配的话,那就所有的其它方法的事务声明都没有实际的效果,
因为你实际上所有的方法调用都只是调用handleRequest方法,再在handleRequest方法中用反射的方式调用实际的业务时,实际方法(像update、save)并没有被拦截,而是拦截的handleRequest方法,那么对于update\save配置的信息就会失效!
有一种方法实出你的想法
你看看关于ActionDispatcher的用法,将handleRequest方法内部的反身代码移到新的类中去。


public class ActionAdatper extends Action {

	protected ActionDispatcher dispatcher ;
	
	protected Action action;
	
	@Override
	public void setServlet(ActionServlet servlet) {
		super.setServlet(servlet);
		this.action.setServlet(servlet);
	}
	public ActionAdatper(Action action){
		action.setServlet(servlet);
		dispatcher = new ActionDispatcher(action,ActionDispatcher.DISPATCH_FLAVOR);
	}
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return dispatcher.execute(mapping, form, request, response);
	}
}



public class NewerDelegatingRequestProcessor extends DelegatingRequestProcessor {
	
	protected Action getDelegateAction(ActionMapping mapping) throws BeansException {
		Action action=super.getDelegateAction(mapping);
		if(action==null){
			return null;
		}
		return new ActionAdatper(action);
	}
	

}


@Transactional(readOnly=false)
public class XXXXAction extends Action {

	/**
	 *
	 * 新增页面初始化处理
	 *
	 */
	public ActionForward create(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
		
	}
	
	
	/**
	 * 修改页面初始化处理
	 * 
	 */
	public ActionForward edit(ActionMapping mapping, ActionForm form,  HttpServletRequest request, HttpServletResponse response) {
		
          }
}
21 楼 sgp2004 2008-12-29  
daquan198163 写道
sgp2004 写道
daquan198163 写道

我猜测原因是ManagerAction的基类导致的,因为框架不是直接调用ManagerAction的方法,而是同意调用Action基类的入口方法(例如handleRequest),然后反射调用你的具体方法,因此你需要为这个入口方法指定事务属性简单办法就是用通配符把所以方法都包括进去:transactionAttributes设为&lt;prop key="*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;

嗯 可以了 嘿嘿 谢谢大哥了!
我的action的基类是dispatchAction 入口方法就不知道怎么指定了,应该是没限制到我action调用的BaseDao的方法,BaseDAO里的方法名是update,save之类的,可能没包含在匹配符号里边 现在只用 “*” 号就可以了 呵呵
还是我自己研究的不深入啊

红色的这部分我没看明白,你好像对Spring AOP事务拦截机制理解有误啊
因为就算配置对了也不可能控制DAO里的方法的,
因为AOP只能拦截到目标对象(这里是action)的方法

那到底是怎么回滚的呢? 我action里的方法addOrg 调用的是dao的delete()和insert()方法,而那两种方法都是通过hibernateTemplate去处理的,每个操作都是个事务,默认是自动提交事务的
20 楼 daquan198163 2008-12-29  
sgp2004 写道
daquan198163 写道

我猜测原因是ManagerAction的基类导致的,因为框架不是直接调用ManagerAction的方法,而是同意调用Action基类的入口方法(例如handleRequest),然后反射调用你的具体方法,因此你需要为这个入口方法指定事务属性简单办法就是用通配符把所以方法都包括进去:transactionAttributes设为&lt;prop key="*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;

嗯 可以了 嘿嘿 谢谢大哥了!
我的action的基类是dispatchAction 入口方法就不知道怎么指定了,应该是没限制到我action调用的BaseDao的方法,BaseDAO里的方法名是update,save之类的,可能没包含在匹配符号里边 现在只用 “*” 号就可以了 呵呵
还是我自己研究的不深入啊

红色的这部分我没看明白,你好像对Spring AOP事务拦截机制理解有误啊
因为就算配置对了也不可能控制DAO里的方法的,
因为AOP只能拦截到目标对象(这里是action)的方法
19 楼 wxlmcqueen 2008-12-29  
AOP 托管 action
18 楼 sgp2004 2008-12-26  
bio1984 写道

有接口吗。。。没接口不能用声明式事务。。。

可以的 我现在已经试验成功了 就是用daquan198163 大哥给的配置方法
17 楼 sgp2004 2008-12-26  
taupo 写道

很久没有用xml配置事务了,忘记了怎么配置了 楼主不是用的STRUTS2吗? 在struts2中可以利用拦截器实现你要的功能 可以自己声明一个annotation,表示某个Action里的方法需要事务,然后在拦截器中对方法的调用进行拦截,如果某个方法声明了这个annotation,那么就手动加上事务

呵呵 我用的还是struts 1.1的 以后试试struts 2的方法 谢谢解答!
16 楼 sgp2004 2008-12-26  
yygybing 写道

你的事务是加在ACTION上的,你ACTION里的方法是包含在“insert*"或"add*"里面的么,如果不是,当然不会起作用。而&lt;prop key="*"&gt;肯定包含所有方法

action里的方法是包含在“insert*"或"add*"里面的 但是调用的dao是用的update save之类的 可能是这样不起作用了 谢谢指点!
15 楼 sgp2004 2008-12-26  
daquan198163 写道

我猜测原因是ManagerAction的基类导致的,因为框架不是直接调用ManagerAction的方法,而是同意调用Action基类的入口方法(例如handleRequest),然后反射调用你的具体方法,因此你需要为这个入口方法指定事务属性简单办法就是用通配符把所以方法都包括进去:transactionAttributes设为&lt;prop key="*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;

嗯 可以了 嘿嘿 谢谢大哥了!
我的action的基类是dispatchAction 入口方法就不知道怎么指定了,应该是没限制到我action调用的BaseDao的方法,BaseDAO里的方法名是update,save之类的,可能没包含在匹配符号里边 现在只用 “*” 号就可以了 呵呵
还是我自己研究的不深入啊
14 楼 WorkingHard?! 2008-12-26  
bio1984 写道
有接口吗。。。没接口不能用声明式事务。。。

哪里说的?
13 楼 taupo 2008-12-26  
很久没有用xml配置事务了,忘记了怎么配置了
楼主不是用的STRUTS2吗?
在struts2中可以利用拦截器实现你要的功能

可以自己声明一个annotation,表示某个Action里的方法需要事务,然后在拦截器中对方法的调用进行拦截,如果某个方法声明了这个annotation,那么就手动加上事务

12 楼 bio1984 2008-12-26  
有接口吗。。。没接口不能用声明式事务。。。
11 楼 yygybing 2008-12-26  
你的事务是加在ACTION上的,你ACTION里的方法是包含在“insert*"或"add*"里面的么,如果不是,当然不会起作用。而<prop key="*">肯定包含所有方法
10 楼 daquan198163 2008-12-26  
readOnly没什么用处,仅仅改善一点性能,不要用它
9 楼 daquan198163 2008-12-26  

我猜测原因是ManagerAction的基类导致的,
因为框架不是直接调用ManagerAction的方法,而是同意调用Action基类的入口方法(例如handleRequest),然后反射调用你的具体方法,因此你需要为这个入口方法指定事务属性
简单办法就是用通配符把所以方法都包括进去:
transactionAttributes设为<prop key="*">PROPAGATION_REQUIRED</prop>

相关推荐

Global site tag (gtag.js) - Google Analytics