日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

spring.net nhibernate 分布布式事务(下)

發布時間:2025/5/22 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring.net nhibernate 分布布式事务(下) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
spring.net nhibernate 分布布式事務(下)

摘自: http://www.cnblogs.com/GoodHelper/archive/2010/07/30/SpringNetDistributedTransaction2.html

Spring.NET實用技巧4——NHibernate分布式事務(下)

  

  上篇,我們已實現了在同一應用程序下的分布式事務——即多Dao層+同Service層,每個Dao對應一個數據庫,一個Service調用多個Dao。但是在一些特定的子系統較多的項目中,開發人員是無法訪問到某個子系統的數據庫,這就意味著不能通過增加Dao層來實現分布式事務。正如一個銀行的軟件系統,記錄了客戶的賬戶信息和存款金額,北京的分公司和上海的分公司分別有自己的數據庫和軟件系統。現在,要實現北京的系統向上海的系統轉賬,然而各自作為開發人員來說,沒有足夠的權限去訪問對方的數據庫,但是可以提供Web Service的方式去訪問其系統服務。這樣,我們就需要實現基于Web Service的分布式事務。

  實現基于Web Service的分布式事務的方法比較多,可以通過.NET企業服務的方式。但是為了更好的實現,我們選擇WCF作為一個分布式應用程序框架。WCF在實現分布式事務中有它的優越之處。其思路在于啟動MSDTC服務,將客戶端的事務以流的方式傳遞到服務器端,在服務器端執行通過時,客戶端再提交事務,相反則回滾事務。

  我們模仿上篇的場景做一個demo,并使用上篇的Dao和Domain。

?

  

  一、啟動MSDTC服務。

?

  二、Service層

  ①.Customer

  

CustomerManager ??? publicinterface ICustomerManager ??? { ??????? CustomerInfo Get(object id);
???????
object Save(CustomerInfo entity);
???????
void Update(CustomerInfo entity); ??? }
???
publicclass CustomerManager : ICustomerManager ??? { ??????? private ICustomerDao Dao { get; set; }
???????
public CustomerInfo Get(object id) ??????? { ??????????? return Dao.Get(id); ??????? }
???????
publicobject Save(CustomerInfo entity) ??????? { ??????????? return Dao.Save(entity); ??????? }
???????
publicvoid Update(CustomerInfo entity) ??????? { ??????????? if (entity.Money >3000) ??????????? { ??????????????? thrownew Exception("訂金上限"); ??????????? } ??????????? Dao.Update(entity); ??????? } ??? }

?

  

?

Service.xml <?xml version="1.0" encoding="utf-8" ?><objects xmlns="http://www.springframework.net">
?
<object id="transactionManager" ??????? type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate21"> ??? <property name="DbProvider" ref="DbProvider"/> ??? <property name="SessionFactory" ref="NHibernateSessionFactory"/> ? </object>
?
<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="BaseTransactionManager"? type="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data" abstract="true"> ??? <property name="PlatformTransactionManager" ref="transactionManager"/> ??? <property name="TransactionAttributes"> ????? <name-values>? ??????? <add key="*" value="PROPAGATION_REQUIRED"/> ????? </name-values> ??? </property> ? </object>
?
<object id="Customer.CustomerManager" parent="BaseTransactionManager"> ??? <property name="Target"> ????? <object type="Customer.Service.Implement.CustomerManager, Customer.Service"> ??????? <property name="Dao" ref="Customer.CustomerDao"/> ????? </object> ??? </property> ? </object>
</objects>

?

?

  ②.Order

  

OrderManager ??? publicinterface IOrderManager ??? { ??????? object Save(OrderInfo entity); ??? }
???
publicclass OrderManager : IOrderManager ??? { ??????? public IOrderDao Dao { get; set; }
???????
publicobject Save(OrderInfo entity) ??????? { ??????????? return Dao.Save(entity); ??????? } ??? }

?

?

Service.xml <?xml version="1.0" encoding="utf-8" ?><objects xmlns="http://www.springframework.net">
?
<object id="transactionManager" ??????? type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate21"> ??? <property name="DbProvider" ref="DbProvider"/> ??? <property name="SessionFactory" ref="NHibernateSessionFactory"/> ? </object>
?
<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="BaseTransactionManager"? type="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data" abstract="true"> ??? <property name="PlatformTransactionManager" ref="transactionManager"/> ??? <property name="TransactionAttributes"> ????? <name-values>? ??????? <add key="*" value="PROPAGATION_REQUIRED"/> ????? </name-values> ??? </property> ? </object>
?
<object id="Order.OrderManager" parent="BaseTransactionManager"> ??? <property name="Target"> ????? <object type="Order.Service.Implement.OrderManager, Order.Service"> ??????? <property name="Dao" ref="Order.OrderDao"/> ????? </object> ??? </property> ? </object>
</objects>

?

  三、服務契約和Host。

  1、契約

  作為服務契約,需要啟用Session,并且設置TransactionFlowOption的等級為Allowed或Mandatory來接收客戶端事務流。

  作為契約的實現部分,需要設置TransactionScopeRequired為true來啟用事務作用域。

?

  ①.Customer

?

CustomerContract ??? [ServiceContract(SessionMode = SessionMode.Required)] ??? publicinterface ICustomerContract ??? { ??????? [OperationContract] ??????? [TransactionFlow(TransactionFlowOption.Allowed)] ??????? CustomerInfo Get(object id);
??????? [OperationContract] ??????? [TransactionFlow(TransactionFlowOption.Allowed)] ???????
object Save(CustomerInfo entity);
??????? [OperationContract] ??????? [TransactionFlow(TransactionFlowOption.Allowed)] ???????
void Update(CustomerInfo entity); ??? }
??? [AspNetCompatibilityRequirements(RequirementsMode
= AspNetCompatibilityRequirementsMode.Required)] ??? publicclass CustomerServer : ICustomerContract ??? { ??????? public ICustomerManager Manager { get; set; }
??????? [OperationBehavior(TransactionScopeRequired
=true)] ??????? public CustomerInfo Get(object id) ??????? { ??????????? return Manager.Get(id); ??????? }
??????? [OperationBehavior(TransactionScopeRequired
=true)] ??????? publicobject Save(CustomerInfo entity) ??????? {
???????????
return Manager.Save(entity); ??????? }
??????? [OperationBehavior(TransactionScopeRequired
=true)] ??????? publicvoid Update(CustomerInfo entity) ??????? { ??????????? Manager.Update(entity); ??????? }

?

?

  ②.Order

  

IOrderContract ??? [ServiceContract(SessionMode = SessionMode.Required)] ??? publicinterface IOrderContract ??? { ??????? [OperationContract] ??????? [TransactionFlow(TransactionFlowOption.Allowed)] ??????? object Save(OrderInfo entity); ??? }
?? [AspNetCompatibilityRequirements(RequirementsMode
= AspNetCompatibilityRequirementsMode.Required)] ??? publicclass OrderServer : IOrderContract ??? { ??????? public IOrderManager Manager { get; set; }
??????? [OperationBehavior(TransactionScopeRequired
=true)] ??????? publicobject Save(OrderInfo entity) ??????? { ??????????? return Manager.Save(entity); ??????? } ??? }

?

?

?

  2、配置

  然而,Spring.NET針對NHibernate的Session管理使用的是OSIV模式(Open Session In View),即使用httpModule去攔截HTTP請求,在每次請求開始時打開Session作用域(SessionScope),最后在請求結束后關閉SessionScope。這樣一來,在客戶端每請求一次時都會打開SessionScope,在請求結束會關閉SessionScope,然后當請求結束后再去處理分布式就會提示“無法使用已釋放對象”的錯誤。所以說,OSIV是無法正常管理分布式事務的。出于上述原因,我們決定在Global.asax的配置,在Session(這里的Session是ASP.NET中的Session)啟動時候打開SessionScope,在Session結束時關閉SessionScope。這樣分布式事務就會與SessionScope同步了。

  最后,在配置appSettings節點增加 ??? <add key="Spring.Data.NHibernate.Support.SessionScope.SessionFactoryObjectName" value="NHibernateSessionFactory"/>

  另外配置WCF的binding時需要選擇一種支持Session的binding(如wsHttpBinding)并且將binding中的transactionFlow屬性設置為true。

  

Global.asax ??? publicclass Global : System.Web.HttpApplication ??? {
???????
protectedvoid Application_Start(object sender, EventArgs e) ??????? { ??????????? log4net.Config.XmlConfigurator.Configure(); ??????? }
???????
protectedvoid Session_Start(object sender, EventArgs e) ??????? { ??????????? SessionScope sessionScope =new SessionScope("appSettings", typeof(SessionScope), false); ??????????? sessionScope.Open(); ??????????? HttpContext.Current.Session["SessionScope"] = sessionScope; ??????? }
??????? ???????
protectedvoid Session_End(object sender, EventArgs e) ??????? { ??????????? SessionScope sessionScope = HttpContext.Current.Session["SessionScope"] as SessionScope; ??????????? if (sessionScope !=null) ??????????? { ??????????????? sessionScope.Close(); ??????????? } ??????? }
??? }

?

?

  ①.Customer

 

Web.config <?xml version="1.0" encoding="utf-8"?><configuration> ? .............. <!--spring配置--> ? <spring xmlns="http://www.springframework.net"> ??? <parsers> ????? <parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data"/> ????? <parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data"/> ??? </parsers> ??? <context> ????? <resource uri="config://spring/objects"/>
?????
<!--Dao--> ????? <resource uri="assembly://Customer.Dao/Customer.Dao.Config/Dao.xml"/> ????? <!--Service--> ????? <resource uri="assembly://Customer.Service/Customer.Service.Config/Service.xml"/>
???
</context> ??? <objects xmlns="http://www.springframework.net" ???????????? xmlns:aop="http://www.springframework.net/aop">
?????
<object id="Customer.Host" type="Customer.Host.Implement.CustomerServer, Customer.Host"> ??????? <property name="Manager" ref="Customer.CustomerManager"/> ????? </object>
???
</objects> ? </spring>
?
<appSettings> ??? <add key="Spring.Data.NHibernate.Support.SessionScope.SessionFactoryObjectName" value="NHibernateSessionFactory"/> ? </appSettings>
?
<system.web> ??? <compilation debug="true" targetFramework="4.0"/>
???
<httpModules> ????? <add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/> ??? </httpModules>
?
</system.web> ? <system.serviceModel> ??? <services> ????? <service name="Customer.Host"> ??????? <endpoint address="" binding="wsHttpBinding" bindingConfiguration="ServerBinding" contract="Customer.Host.ICustomerContract"/> ??????? <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> ????? </service> ??? </services> ??? <bindings> ????? <wsHttpBinding > ??????? <binding name="ServerBinding" transactionFlow="true"> ??????? </binding> ????? </wsHttpBinding> ??? </bindings> ??? <behaviors> ????? <serviceBehaviors> ??????? <behavior> ????????? <!-- 為避免泄漏元數據信息,請在部署前將以下值設置為 false 并刪除上面的元數據終結點 --> ????????? <serviceMetadata httpGetEnabled="true"/> ????????? <!-- 要接收故障異常詳細信息以進行調試,請將以下值設置為 true。在部署前設置為 false 以避免泄漏異常信息 --> ????????? <serviceDebug includeExceptionDetailInFaults="true"/> ??????? </behavior> ????? </serviceBehaviors> ??? </behaviors> ??? <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/> ? </system.serviceModel><system.webServer> ??? <modules runAllManagedModulesForAllRequests="true"/> ? </system.webServer> ? </configuration>

?

?

?

<%@ ServiceHost Language="C#" Debug="true" Service="Customer.Host" Factory="Spring.ServiceModel.Activation.ServiceHostFactory"%>

?

?

  ②.Order

  

Web.config <?xml version="1.0" encoding="utf-8"?><configuration>
? ..........
?
<!--spring配置--> ? <spring xmlns="http://www.springframework.net"> ??? <parsers> ????? <parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data"/> ????? <parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data"/> ??? </parsers> ??? <context> ????? <resource uri="config://spring/objects"/>
?????
<!--Dao--> ????? <resource uri="assembly://Order.Dao/Order.Dao.Config/Dao.xml"/> ????? <!--Service--> ????? <resource uri="assembly://Order.Service/Order.Service.Config/Service.xml"/>
???
</context> ??? <objects xmlns="http://www.springframework.net" ???????????? xmlns:aop="http://www.springframework.net/aop">
?????
<object id="Order.Host" type="Order.Host.Implement.OrderServer, Order.Host"> ??????? <property name="Manager" ref="Order.OrderManager"/> ????? </object>
???
</objects> ? </spring>
?
<appSettings> ??? <add key="Spring.Data.NHibernate.Support.SessionScope.SessionFactoryObjectName" value="NHibernateSessionFactory"/> ? </appSettings>
?
<system.web> ??? <compilation debug="true" targetFramework="4.0"/>
???
<httpModules> ????? <add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/> ??? </httpModules>
?
</system.web> ? <system.serviceModel> ??? <services> ????? <service name="Order.Host"> ??????? <endpoint address="" binding="wsHttpBinding" bindingConfiguration="ServerBinding" contract="Order.Host.IOrderContract"/> ??????? <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> ????? </service> ??? </services> ??? <bindings> ????? <wsHttpBinding > ??????? <binding name="ServerBinding" transactionFlow="true"? > ??????? </binding> ????? </wsHttpBinding> ??? </bindings> ??? <behaviors> ????? <serviceBehaviors> ??????? <behavior> ????????? <!-- 為避免泄漏元數據信息,請在部署前將以下值設置為 false 并刪除上面的元數據終結點 --> ????????? <serviceMetadata httpGetEnabled="true"/> ????????? <!-- 要接收故障異常詳細信息以進行調試,請將以下值設置為 true。在部署前設置為 false 以避免泄漏異常信息 --> ????????? <serviceDebug includeExceptionDetailInFaults="true"/> ??????? </behavior> ????? </serviceBehaviors> ??? </behaviors> ??? <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/> ? </system.serviceModel><system.webServer> ??? <modules runAllManagedModulesForAllRequests="true"/> ? </system.webServer> ? </configuration>

?

?

?

<%@ ServiceHost Language="C#" Debug="true" Service="Order.Host" Factory="Spring.ServiceModel.Activation.ServiceHostFactory"%>

?

?

  四、客戶端

?

HostTest [TestFixture] ??? publicclass HostTest ??? { ??????? private CustomerContractClient customerProxy;
???????
private OrderContractClient orderProxy;
??????? [SetUp] ???????
publicvoid Init() ??????? { ??????????? customerProxy =new CustomerContractClient(); ??????????? orderProxy =new OrderContractClient(); ??????? }
??????? [Test] ???????
publicvoid InitData() ??????? { ??????????? using (TransactionScope scope =new TransactionScope()) ??????????? { ??????????????? customerProxy.Save(new CustomerInfo ??????????????? { ??????????????????? Name ="劉冬" ??????????????? });
??????????????? scope.Complete(); ??????????? } ??????? }
??????? [Test] ???????
publicvoid DistributedTransactionTest() ??????? { ??????????? using (TransactionScope scope =new TransactionScope()) ??????????? { ??????????????? try ??????????????? { ??????????????????? CustomerInfo customer = customerProxy.Get(1); ??????????????????? orderProxy.Save(new OrderInfo ??????????????????? { ??????????????????????? Address ="中國北京", ??????????????????????? CustomerId = (int)customer.ID, ??????????????????????? OrderDate = DateTime.Now ??????????????????? }); ??????????????????? customer.Money +=1000; ??????????????????? customerProxy.Update(customer); ??????????????????? scope.Complete(); ??????????????????? Console.WriteLine("分布式事務已提交"); ??????????????? } ??????????????? catch (Exception ex) ??????????????? { ??????????????????? Transaction.Current.Rollback(); ??????????????????? Console.WriteLine("發送錯誤:分布式事務已回滾"); ??????????????? } ??????????? } ??????? } ??? }

?

?

?

  

?

  五、運行效果

  1.初始化數據

  

?

  2.建立第一張訂單,訂金小于3000

?

  

?

  

  3.建立第一張訂單,訂金小于3000

?

?

  4.建立第一張訂單,訂金等于3000

?

?

  5.建立第一張訂單,訂金大于3000,事務回滾。

?

?

?

  好了,基于Web Service的分布式事務已經實現了。

?

  代碼下載

  出處:http://www.cnblogs.com/GoodHelper/archive/2010/07/30/SpringNetDistributedTransaction2.html

  歡迎轉載,但需保留版權。

posted on 2013-02-23 14:49?Alfa 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/wuyifu/archive/2013/02/23/2923436.html

總結

以上是生活随笔為你收集整理的spring.net nhibernate 分布布式事务(下)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。