Spring.net+NHibernate+WCF存储数据问题
现在我通过Spring.net+NHibernate+WCF来实现通过服务存储数据。总是报
System.Transactions.TransactionAbortedException: 已中止事务。
在 System.Transactions.TransactionStatePromotedAborted.PromotedTransactionOutcome(InternalTransaction tx)
在 System.Transactions.TransactionStatePromotedEnded.EndCommit(InternalTransaction tx)
在 System.Transactions.CommittableTransaction.Commit()
在 System.Transactions.TransactionScope.InternalDispose()
在 System.Transactions.TransactionScope.Dispose()
在 System.Windows.Forms.Control.OnClick(EventArgs e)
在 System.Windows.Forms.Button.OnClick(EventArgs e)
在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
在 System.Windows.Forms.Control.WndProc(Message& m)
在 System.Windows.Forms.ButtonBase.WndProc(Message& m)
在 System.Windows.Forms.Button.WndProc(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
我是通过spring.net来实现依赖注入和宿主服务,并且设置了分布式事务管理。
<object id="transactionManager"
type="Spring.Data.Core.TxScopeTransactionManager, Spring.Data">
</object>
<!-- Exception translation object post processor
<object type="Spring.Dao.Attributes.PersistenceExceptionTranslationPostProcessor, Spring.Data"/> -->
<object id="transactionInterceptor"
type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
<property name="TransactionManager" ref="transactionManager"/>
<property name="TransactionAttributeSource">
<object type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data"/>
</property>
</object>
<!---->
<object id="TxProxyConfigurationTemplate" abstract="true"
type="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data">
<property name="PlatformTransactionManager" ref="transactionManager"/>
<property name="TransactionAttributes">
<name-values>
<!-- Add common methods across your services here-->
<add key="Get*" value="PROPAGATION_REQUIRED,readOnly"/>
<add key="Save*" value="PROPAGATION_REQUIRED"/>
<add key="Update*" value="PROPAGATION_REQUIRED"/>
<add key="Load*" value="PROPAGATION_REQUIRED,readOnly"/>
<add key="Delete*" value="PROPAGATION_REQUIRED"/>
<add key="*" value="PROPAGATION_REQUIRED"/>
</name-values>
</property>
</object>
<!---->
<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="UserInfoDal" parent="TxProxyConfigurationTemplate">
<property name="Target">
<object type="Service.DataBase.DAL.UserInfoDal,Service.DataBase.DAL">
<property name="HibernateTemplate" ref="HibernateTemplate"/>
</object>
</property>
</object>
在WCF服务端
[ServiceContract(SessionMode=SessionMode.Required)]
public inte易做图ce IUserInfoService
{
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
object Save(SecUserInfo userInfo);
}
服务实现
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.NotAllowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,
TransactionIsolationLevel = IsolationLevel.Serializable,
TransactionTimeout = "00:09:30")]
[BindingRequirement(TransactionFlowEnabled=true)]
public class UserInfoService:IUserInfoService
{
public IUserInfoDal UserDal { get; set; }
[OperationBehavior(TransactionScopeRequired = true)]
public object Save(UserInfo userInfo)
{
object id = null;
id = UserDal.Save(userInfo);
return id;
}
客户端
private void button2_Click(object sender, EventArgs e)
{
UserInfo user = new UserInfo();
user.birthday = DateTime.Now;
user.createDate = DateTime.Now;
user.lastLoginTime = DateTime.Now;
user.lastModifyDate = DateTime.Now;
user.userName = "1111";
user.passWord = "3333";
user.userNo = "3333";
userClient = cxt.GetObject("NetTcpBinding_IUserInfoService") as IUserInfoService;
string id = "";
try
{
TransactionOptions option=new TransactionOptions();
option.IsolationLevel=IsolationLevel.Serializable;
option.Timeout = TimeSpan.FromMinutes(5);
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, option))
{
id = (string)userClient.Save(user);
scope.Complete();
}
}
catch (TransactionAbortedException ex)
{
logger.Error(ex.Message);
throw;
}
catch (Exception ex)
{}
(userClient as ICommunicationObject).Close();
MessageBox.Show(id);
}
我这有点疑惑,
1、spring.net的事务和wcf的事务是一个事务吗?
2、spring.net的事务管理在针对方法上时,但跳出该方法是不是事务就彻底提交了,最终导致客户端收到“已中止事务”的异常?如果是该怎么解决呢?
现在特别着急解决这个问题,跪求高手指教。
--------------------编程问答-------------------- spring.net的事务管理 一直么用过。
补充:.NET技术 , Web Services