这两天帮朋友看了个hibernate事务问题,发现他们的系统中存在这类问题:
为每个Entity建立了一个manager,事务由spring.net管理。出现manager1出错后,manager2无法回滚。我问他们这种处理方法从哪来?朋友说博客园……
我上去看了看,确实如此。唉,我只能告诉他,他对manager的作用理解错误。
一个manager对应一个entity,哪么manager还有什么意义?
不知道别人怎么看,在这种系统中,一个manager应该是一个实际业务对业务所包含的Entity的操作(也就是说manager的一个add方法,可能同时更新多张表),这样才能确保事务在出错后正常回滚。
并且,一个系统如果有非常多的表,这么多的manager如何维护?
正好我这里做过类似的东西,上部分配置及代码。
注:只要名称是Service结尾即可。
View Code
<
object
id
="HibernateTemplate"
type
="Spring.Data.NHibernate.Generic.HibernateTemplate"
>
< property name ="SessionFactory" ref ="NHibernateSessionFactory" />
< property name ="TemplateFlushMode" value ="Auto" />
< property name ="CacheQueries" value ="true" />
</ object >
< object id ="transactionManager" type ="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate31" >
< property name ="DbProvider" ref ="DbProvider" />
< property name ="SessionFactory" ref ="NHibernateSessionFactory" />
</ object >
< object type ="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator,Spring.Aop" >
< property name ="ObjectNames" >
< list >
< value > *Service </ value >
</ list >
</ property >
< property name ="interceptorNames" >
< list >
< value > transactionInterceptorName </ value >
</ list >
</ property >
</ object >
<!-- 拦截器,定义事务策略 -->
< object id ="transactionInterceptorName" type ="Spring.Transaction.Interceptor.TransactionInterceptor,Spring.Data" >
< property name ="transactionAttributes" >
< name-values >
< add key ="*" value ="PROPAGATION_REQUIRED" /> <!-- 事务策略定义 -->
</ name-values >
</ property >
< property name ="transactionManager" >
< ref local ="transactionManager" />
</ property >
</ object >
< property name ="SessionFactory" ref ="NHibernateSessionFactory" />
< property name ="TemplateFlushMode" value ="Auto" />
< property name ="CacheQueries" value ="true" />
</ object >
< object id ="transactionManager" type ="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate31" >
< property name ="DbProvider" ref ="DbProvider" />
< property name ="SessionFactory" ref ="NHibernateSessionFactory" />
</ object >
< object type ="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator,Spring.Aop" >
< property name ="ObjectNames" >
< list >
< value > *Service </ value >
</ list >
</ property >
< property name ="interceptorNames" >
< list >
< value > transactionInterceptorName </ value >
</ list >
</ property >
</ object >
<!-- 拦截器,定义事务策略 -->
< object id ="transactionInterceptorName" type ="Spring.Transaction.Interceptor.TransactionInterceptor,Spring.Data" >
< property name ="transactionAttributes" >
< name-values >
< add key ="*" value ="PROPAGATION_REQUIRED" /> <!-- 事务策略定义 -->
</ name-values >
</ property >
< property name ="transactionManager" >
< ref local ="transactionManager" />
</ property >
</ object >
具体的Service
Service接口
public
interface
TxImplementService
{
IHibernateOperations HibernateTemplate { get ; set ; }
void AddTxImplement();
}
{
IHibernateOperations HibernateTemplate { get ; set ; }
void AddTxImplement();
}
Service实现
public
class
TxServiceImpl : TxImplementService
{
public IHibernateOperations HibernateTemplate { get ; set ; }
public void AddTxImplement()
{
Entity.Model.RT03 rt03 = new Entity.Model.RT03();
rt03.RT03PK.RTB001 = " 0001 " ;
rt03.RT03PK.RTC001 = " 0001 " ;
rt03.RTC002 = " 0002 " ;
rt03.RTC003 = " 003 " ;
rt03.RTC004 = " 004 " ;
RTP.Entity.Model.RT01 rt01 = new Entity.Model.RT01();
rt01.RTA001 = " 0001 " ;
rt01.RTA002 = " 0002 " ;
this .HibernateTemplate.Save(rt01);
this .HibernateTemplate.Save(rt03);
}
}
{
public IHibernateOperations HibernateTemplate { get ; set ; }
public void AddTxImplement()
{
Entity.Model.RT03 rt03 = new Entity.Model.RT03();
rt03.RT03PK.RTB001 = " 0001 " ;
rt03.RT03PK.RTC001 = " 0001 " ;
rt03.RTC002 = " 0002 " ;
rt03.RTC003 = " 003 " ;
rt03.RTC004 = " 004 " ;
RTP.Entity.Model.RT01 rt01 = new Entity.Model.RT01();
rt01.RTA001 = " 0001 " ;
rt01.RTA002 = " 0002 " ;
this .HibernateTemplate.Save(rt01);
this .HibernateTemplate.Save(rt03);
}
}
Service配置
<
objects
xmlns
="http://www.springframework.net"
>
< object id ="TxService" type ="RTP.Services.Core.bo.TxServiceImpl" >
< property name ="HibernateTemplate" ref ="HibernateTemplate" />
</ object >
</ objects >
< object id ="TxService" type ="RTP.Services.Core.bo.TxServiceImpl" >
< property name ="HibernateTemplate" ref ="HibernateTemplate" />
</ object >
</ objects >
经测试,以上方法在asp.net mvc3/spring.net 1.3.2/NHibernate 3.1/oracle 10g/windows2008下事务可正常回滚。
目前,朋友正在痛苦的重构着