日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Spring.NET实用技巧3——NHibernate分布式事务(上)

發布時間:2025/7/14 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring.NET实用技巧3——NHibernate分布式事务(上) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  

  在使用NHibernate作為持久層框架時,多數據庫操作是一個比較難解決的問題。并且很多網友在給我發的eamil中經常談到此問題。由于NHibernate是一種框架,不能像ADO.NET那樣直接用SQL語句操作數據庫,在動態改變DbConnection時比較麻煩,而且NHibernate目前并不完全支持多數據庫,所以實現多數據庫的操作是個棘手的問題。

  回想一下,在使用ADO.NET實現多數據庫的時候,無非是增加多個DbConnection,以后在每次事務結束后提交事務。所以說多數據庫的實現難點在于實現分布式事務。那么,什么是分布式事務?分布式事務是指事務的參與者、支持事務的服務器、資源服務器以及事務管理器分別位于不同的分布式系統的不同節點之上。為了實現分布式事務,需要使用下面將介紹的兩階段提交協議。 階段一:開始向事務涉及到的全部資源發送提交前信息。此時,事務涉及到的資源還有最后一次機會來異常結束事務。如果任意一個資源決定異常結束事務,則整個事務取消,不會進行資源的更新。否則,事務將正常執行,除非發生災難性的失敗。為了防止會發生災難性的失敗,所有資源的更新都會寫入到日志中。這些日志是永久性的,因此,這些日志會幸免遇難并且在失敗之后可以重新對所有資源進行更新。? 階段二:只在階段一沒有異常結束的時候才會發生。此時,所有能被定位和單獨控制的資源管理器都將開始執行真正的數據更新。 在分布式事務兩階段提交協議中,有一個主事務管理器負責充當分布式事務協調器的角色。事務協調器負責整個事務并使之與網絡中的其他事務管理器協同工作。 為了實現分布式事務,必須使用一種協議在分布式事務的各個參與者之間傳遞事務上下文信息,IIOP便是這種協議。這就要求不同開發商開發的事務參與者必須支持一種標準協議,才能實現分布式的事務。

  由于Spring.NET框架的出現,便很好的解決了這一點——分布式事務處理(查詢此博客)。TxScopePlatformTransactionManagerSystem.Transactions提供的本地/分布式的事務管理器。我們配置TxScopePlatformTransactionManager 則能夠實現分布式事務處理。

  

  下面,我建立兩個數據庫:一個數據庫為Customer,用于存放客戶資料數據;另一個數據庫為Order,用于存放客戶的訂單數據。當某個客戶增加訂單成功時,則更新該客戶的訂金余額。我們做一個業務判斷,該客戶的余額不能超過3000,當超過3000時則拋出異常。

  實現步驟如下:

  一、啟動MSDTC服務。運行->cmd輸入->net start msdtc

?

?

?  二、代碼實現

  

?

  1.Domain

?

  ①.Customer

public?class?CustomerInfo
????{
????????
public?virtual?int??ID?{?get;?set;?}

????????
public?virtual?string?Name?{?get;?set;?}

????????
public?virtual?decimal?Money?{?get;?set;?}
????}

?

?

?

CustomerInfo.hbm.xml <?xml?version="1.0"?encoding="utf-8"??>

<hibernate-mapping?xmlns="urn:nhibernate-mapping-2.2"?assembly="Customer.Domain"?namespace="Customer.Domain">
??
<class?name="CustomerInfo"?table="T_Customer"?lazy="true"?>

????
<id?name="ID"?column="id"?type="Int32"?>
??????
<generator?class="native"?/>
????
</id>

????
<property?name="Name"?type="string">
??????
<column?name="Name"?length="50"/>
????
</property>

????
<property?name="Money"?type="decimal">
??????
<column?name="Money"?precision="16"?scale="2"/>
????
</property>

??
</class>
</hibernate-mapping>

?

?

  ②.Order

?

OrderInfo public?class?OrderInfo
????{
????????
public?virtual?int??ID?{?get;?set;?}

????????
public?virtual?int?CustomerId?{?get;?set;?}

????????
public?virtual?DateTime?OrderDate?{?get;?set;?}

????????
public?virtual?string?Address?{?get;?set;?}
????}

?

?

?

OrderInfo.hbm.xml <?xml?version="1.0"?encoding="utf-8"??>

<hibernate-mapping?xmlns="urn:nhibernate-mapping-2.2"?assembly="Order.Domain"?namespace="Order.Domain">
??
<class?name="OrderInfo"?table="T_Order"?lazy="true"?>

????
<id?name="ID"?column="ID"?type="Int32"?>
??????
<generator?class="native"?/>
????
</id>

????
<property?name="CustomerId"?type="int">
??????
<column?name="CustomerId"/>
????
</property>

????
<property?name="OrderDate"?type="DateTime">
??????
<column?name="OrderDate"/>
????
</property>

????
<property?name="Address"?type="string">
??????
<column?name="Address"?length="200"/>
????
</property>

??
</class>
</hibernate-mapping>

?

?

?  2.Dao

  ①.Customer

?

CustomerDao public?interface?ICustomerDao
????{
????????CustomerInfo?Get(
object?id);

????????
object?Save(CustomerInfo?entity);

????????
void?Update(CustomerInfo?entity);
????}

public?class?CustomerDao?:?HibernateDaoSupport,?ICustomerDao
????{
????????
public?virtual?object?Save(CustomerInfo?entity)
????????{
????????????
return?this.HibernateTemplate.Save(entity);
????????}

????????
public?virtual?CustomerInfo?Get(object?id)
????????{
????????????
return?this.HibernateTemplate.Get<CustomerInfo>(id);
????????}


????????
public?void?Update(CustomerInfo?entity)
????????{
????????????
this.HibernateTemplate.Update(entity);
????????}
????}

?

?

?

?

CustomerDao.xml <?xml?version="1.0"?encoding="utf-8"??>
<objects?xmlns="http://www.springframework.net"
?????????xmlns:db
="http://www.springframework.net/database">
?
??
<object?type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer,?Spring.Core">
????
<property?name="ConfigSections"?value="databaseSettings"/>
??
</object>

??
<db:provider?id="Customer.DbProvider"?provider="SqlServer-2.0"
???????????????connectionString
="Server=.;database=Customer;uid=sa;pwd=;"/>

??
<object?id="Customer.NHibernateSessionFactory"?type="Spring.Data.NHibernate.LocalSessionFactoryObject,?Spring.Data.NHibernate21">
????
<property?name="DbProvider"?ref="Customer.DbProvider"/>
????
<property?name="MappingAssemblies">
??????
<list>
????????
<value>Customer.Domain</value>
??????
</list>
????
</property>
????
<property?name="HibernateProperties">
??????
<dictionary>
????????
<entry?key="hibernate.connection.provider"?value="NHibernate.Connection.DriverConnectionProvider"/>
????????
<!--SqlServer連接-->
????????
<entry?key="dialect"?value="NHibernate.Dialect.MsSql2000Dialect"/>
????????
<entry?key="hibernate.connection.driver_class"?value="NHibernate.Driver.SqlClientDriver"/>

????????
<entry?key="use_outer_join"?value="true"/>
????????
<entry?key="show_sql"?value="true"/>
????????
<!--自動建表(反向映射)-->
????????
<entry?key="hbm2ddl.auto"?value="update"/>
????????
<!--批量更新-->
????????
<entry?key="adonet.batch_size"?value="0"/>
????????
<!--超時時間-->
????????
<entry?key="command_timeout"?value="60"/>
????????
<!--啟用二級緩存-->
????????
<entry?key="cache.use_second_level_cache"?value="false"/>
????????
<!--啟動查詢緩存-->
????????
<entry?key="cache.use_query_cache"?value="false"/>
????????
<entry?key="query.substitutions"?value="true?1,?false?0,?yes?'Y',?no?'N'"/>
????????
<entry?key="proxyfactory.factory_class"?value="NHibernate.ByteCode.LinFu.ProxyFactoryFactory,?NHibernate.ByteCode.LinFu"/>
??????
</dictionary>
????
</property>
????
<property?name="ExposeTransactionAwareSessionFactory"?value="true"?/>
??
</object>

??
<object?id="Customer.HibernateTemplate"?type="Spring.Data.NHibernate.Generic.HibernateTemplate">
????
<property?name="SessionFactory"?ref="Customer.NHibernateSessionFactory"?/>
????
<property?name="TemplateFlushMode"?value="Auto"?/>
????
<property?name="CacheQueries"?value="true"?/>
??
</object>


??
<!--?Dao?-->
??
<object?id="Customer.CustomerDao"?type="Customer.Dao.Implement.CustomerDao,Customer.Dao">
????
<property?name="HibernateTemplate"?ref="Customer.HibernateTemplate"/>
??
</object>

</objects>

?

?

  ②.Order

?

OrderDao public?interface?IOrderDao
????{
????????
object?Save(OrderInfo?entity);
????}

?
public?class?OrderDao?:?HibernateDaoSupport,?IOrderDao
????{
????????
public?virtual?object?Save(OrderInfo?entity)
????????{
????????????
return?this.HibernateTemplate.Save(entity);
????????}
????}

?

?

?

?

Order.xml <?xml?version="1.0"?encoding="utf-8"??>
<objects?xmlns="http://www.springframework.net"
?????????xmlns:db
="http://www.springframework.net/database">
?
??
<object?type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer,?Spring.Core">
????
<property?name="ConfigSections"?value="databaseSettings"/>
??
</object>

??
<db:provider?id="Order.DbProvider"?provider="SqlServer-2.0"
???????????????connectionString
="Server=.;database=Order;uid=sa;pwd=;"/>

??
<object?id="Order.NHibernateSessionFactory"?type="Spring.Data.NHibernate.LocalSessionFactoryObject,?Spring.Data.NHibernate21">
????
<property?name="DbProvider"?ref="Order.DbProvider"/>
????
<property?name="MappingAssemblies">
??????
<list>
????????
<value>Order.Domain</value>
??????
</list>
????
</property>
????
<property?name="HibernateProperties">
??????
<dictionary>
????????
<entry?key="hibernate.connection.provider"?value="NHibernate.Connection.DriverConnectionProvider"/>
????????
<!--SqlServer連接-->
????????
<entry?key="dialect"?value="NHibernate.Dialect.MsSql2000Dialect"/>
????????
<entry?key="hibernate.connection.driver_class"?value="NHibernate.Driver.SqlClientDriver"/>

????????
<entry?key="use_outer_join"?value="true"/>
????????
<entry?key="show_sql"?value="true"/>
????????
<!--自動建表(反向映射)-->
????????
<entry?key="hbm2ddl.auto"?value="update"/>
????????
<!--批量更新-->
????????
<entry?key="adonet.batch_size"?value="0"/>
????????
<!--超時時間-->
????????
<entry?key="command_timeout"?value="60"/>
????????
<!--啟用二級緩存-->
????????
<entry?key="cache.use_second_level_cache"?value="false"/>
????????
<!--啟動查詢緩存-->
????????
<entry?key="cache.use_query_cache"?value="false"/>
????????
<entry?key="query.substitutions"?value="true?1,?false?0,?yes?'Y',?no?'N'"/>
????????
<entry?key="proxyfactory.factory_class"?value="NHibernate.ByteCode.LinFu.ProxyFactoryFactory,?NHibernate.ByteCode.LinFu"/>
??????
</dictionary>
????
</property>
????
<property?name="ExposeTransactionAwareSessionFactory"?value="true"?/>
??
</object>

??
<object?id="Order.HibernateTemplate"?type="Spring.Data.NHibernate.Generic.HibernateTemplate">
????
<property?name="SessionFactory"?ref="Order.NHibernateSessionFactory"?/>
????
<property?name="TemplateFlushMode"?value="Auto"?/>
????
<property?name="CacheQueries"?value="true"?/>
??
</object>


??
<!--?Dao?-->
??
<object?id="Order.OrderDao"?type="Order.Dao.Implement.OrderDao,Order.Dao">
????
<property?name="HibernateTemplate"?ref="Order.HibernateTemplate"/>
??
</object>

</objects>

?

?

  三、Service

  

OrderManager ????public?interface?IOrderManager
????{
????????
void?CreateOrder(OrderInfo?order,?decimal?money);

????????
object?SaveCustomer(CustomerInfo?customer);
????}

public?class?OrderManager?:?IOrderManager
????{
????????
public?ICustomerDao?CustomerDao?{?get;?set;?}

????????
public?IOrderDao?OrderDao?{?get;?set;?}

????????[Transaction]
????????
public?void?CreateOrder(OrderInfo?order,decimal?money)
????????{
????????????CustomerInfo?customer?
=?CustomerDao.Get(order.CustomerId);
????????????OrderDao.Save(order);
????????????

????????????
if?(customer.Money?>=?3000)
????????????{
????????????????
throw?new?Exception("訂金額度上限");
????????????}
       customer.Money?+=?money;
????????????CustomerDao.Update(customer);
????????}

????????[Transaction]
????????
public?object?SaveCustomer(CustomerInfo?customer)
????????{
????????????
return?CustomerDao.Save(customer);
????????}
????}

?

?

?

Service.xml <?xml?version="1.0"?encoding="utf-8"??>
<objects?xmlns="http://www.springframework.net"
?????????xmlns:db
="http://www.springframework.net/database"
?????????xmlns:tx
="http://www.springframework.net/tx">

??
<object?id="transactionManager"
??????????type
="Spring.Data.Core.TxScopeTransactionManager,?Spring.Data">
??
</object>

??
<!--?Service?-->
??
<object?id="Service.OrderManager"?type="Service.Implement.OrderManager,Service">
????
<property?name="CustomerDao"?ref="Customer.CustomerDao"/>
????
<property?name="OrderDao"?ref="Order.OrderDao"/>
??
</object>

??
<tx:attribute-driven/>

</objects>

?

?

  四、Test

?

Test ?[TestFixture]
????
public?class?ServiceTest
????{
????????
private?IApplicationContext?applicationContext;
????????
????????[SetUp]
????????
public?void?Init()
????????{
????????????log4net.Config.XmlConfigurator.Configure();
????????????applicationContext?
=?ContextRegistry.GetContext();
????????}

????????[Test]
????????
public?void?InitData()
????????{
????????????CustomerInfo?customer?
=?new?CustomerInfo
????????????{
????????????????Name?
=?"劉冬"
????????????};
????????????IOrderManager?manager?
=?(IOrderManager)applicationContext.GetObject("Service.OrderManager");
????????????manager.SaveCustomer(customer);
????????}

????????[Test]
????????
public?void?CreateOrderTest()
????????{
????????????IOrderManager?manager?
=?(IOrderManager)applicationContext.GetObject("Service.OrderManager");
????????????manager.CreateOrder(
new?OrderInfo
????????????{
????????????????Address?
=?"中國北京",
????????????????CustomerId?
=?1,
????????????????OrderDate?
=?DateTime.Now
????????????},?
1000);
????????}
????}

?

?

?

App.config <?xml?version="1.0"?>
<configuration>
??
<configSections>

????
<sectionGroup?name="spring">
??????
<section?name="context"?type="Spring.Context.Support.ContextHandler,?Spring.Core"/>
??????
<section?name="parsers"?type="Spring.Context.Support.NamespaceParsersSectionHandler,?Spring.Core"/>
??????
<section?name="objects"?type="Spring.Context.Support.DefaultSectionHandler,?Spring.Core"/>
????
</sectionGroup>

????
<section?name="log4net"?type="log4net.Config.Log4NetConfigurationSectionHandler,?log4net"?/>
????
<section?name="databaseSettings"?type="System.Configuration.NameValueSectionHandler"?/>
??
</configSections>


??
<!--log4net配置-->
??
<log4net?debug="true">
????
<appender?name="LogFileAppender"?type="log4net.Appender.FileAppender">
??????
<param?name="File"?value="Logs\Log.log"?/>
??????
<param?name="datePattern"?value="MM-dd?HH:mm"?/>
??????
<param?name="AppendToFile"?value="true"?/>
??????
<layout?type="log4net.Layout.PatternLayout">
????????
<param?name="ConversionPattern"?value="%d?[%t]?%-5p?%c?[%x]?-?%m%n"?/>
??????
</layout>
????
</appender>
????
<appender?name="HttpTraceAppender"?type="log4net.Appender.ASPNetTraceAppender">
??????
<layout?type="log4net.Layout.PatternLayout">
????????
<param?name="ConversionPattern"?value="%d?[%t]?%-5p?%c?[%x]?-?%m%n"?/>
??????
</layout>
????
</appender>
????
<appender?name="EventLogAppender"?type="log4net.Appender.EventLogAppender">
??????
<layout?type="log4net.Layout.PatternLayout">
????????
<param?name="ConversionPattern"?value="%d?[%t]?%-5p?%c?[%x]?-?%m%n"?/>
??????
</layout>
????
</appender>
????
<appender?name="RollingLogFileAppender"?type="log4net.Appender.RollingFileAppender">
??????
<param?name="File"?value="Logs/Log.log"?/>
??????
<param?name="AppendToFile"?value="true"?/>
??????
<param?name="MaxSizeRollBackups"?value="10"?/>
??????
<param?name="MaximumFileSize"?value="100K"?/>
??????
<param?name="RollingStyle"?value="Size"?/>
??????
<param?name="StaticLogFileName"?value="true"?/>
??????
<layout?type="log4net.Layout.PatternLayout">
????????
<param?name="ConversionPattern"?value="%d?[%t]?%-5p?%c?[%x]?-?%m%n"?/>
??????
</layout>
????
</appender>
????
<root>
??????
<level?value="ALL"?/>
??????
<appender-ref?ref="RollingLogFileAppender"?/>
????
</root>
??
</log4net>

??
<!--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"?/>
??????
<resource?uri="assembly://Order.Dao/Order.Dao.Config/Dao.xml"?/>
??????
<!--Service-->
??????
<resource?uri="assembly://Service/Service.Config/Service.xml"?/>

????
</context>
????
<objects?xmlns="http://www.springframework.net"/>
??
</spring>

??
<startup><supportedRuntime?version="v4.0"?sku=".NETFramework,Version=v4.0"/></startup></configuration>

?

?

?

  運行結果如下:

  一、初始化數據:

  

?

  

?

  二、建立第一個訂單(插入第一次數據),訂金小于3000

?

  三、建立第一個訂單(插入第二次數據),訂金小于3000

?

  四、建立第一個訂單(插入第三次數據),訂金等于3000

?

  五、建立第一個訂單(插入第四次數據),訂金超過3000

  

?

?

  從運行結果上看到,當我們創建第四張訂單時,由于訂金超過3000后拋出異常,數據實現回滾。這樣分布式事務便實現了。

?

  代碼下載

  出處:http://www.cnblogs.com/GoodHelper/archive/2010/07/29/SpringNetDistributedTransaction1.html

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

轉載于:https://www.cnblogs.com/GoodHelper/archive/2010/07/29/SpringNetDistributedTransaction1.html

總結

以上是生活随笔為你收集整理的Spring.NET实用技巧3——NHibernate分布式事务(上)的全部內容,希望文章能夠幫你解決所遇到的問題。

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