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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

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

發(fā)布時(shí)間:2025/7/14 asp.net 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring.NET实用技巧3——NHibernate分布式事务(上) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  

  在使用NHibernate作為持久層框架時(shí),多數(shù)據(jù)庫(kù)操作是一個(gè)比較難解決的問(wèn)題。并且很多網(wǎng)友在給我發(fā)的eamil中經(jīng)常談到此問(wèn)題。由于NHibernate是一種框架,不能像ADO.NET那樣直接用SQL語(yǔ)句操作數(shù)據(jù)庫(kù),在動(dòng)態(tài)改變DbConnection時(shí)比較麻煩,而且NHibernate目前并不完全支持多數(shù)據(jù)庫(kù),所以實(shí)現(xiàn)多數(shù)據(jù)庫(kù)的操作是個(gè)棘手的問(wèn)題。

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

  由于Spring.NET框架的出現(xiàn),便很好的解決了這一點(diǎn)——分布式事務(wù)處理(查詢(xún)此博客)。TxScopePlatformTransactionManagerSystem.Transactions提供的本地/分布式的事務(wù)管理器。我們配置TxScopePlatformTransactionManager 則能夠?qū)崿F(xiàn)分布式事務(wù)處理。

  

  下面,我建立兩個(gè)數(shù)據(jù)庫(kù):一個(gè)數(shù)據(jù)庫(kù)為Customer,用于存放客戶(hù)資料數(shù)據(jù);另一個(gè)數(shù)據(jù)庫(kù)為Order,用于存放客戶(hù)的訂單數(shù)據(jù)。當(dāng)某個(gè)客戶(hù)增加訂單成功時(shí),則更新該客戶(hù)的訂金余額。我們做一個(gè)業(yè)務(wù)判斷,該客戶(hù)的余額不能超過(guò)3000,當(dāng)超過(guò)3000時(shí)則拋出異常。

  實(shí)現(xiàn)步驟如下:

  一、啟動(dòng)MSDTC服務(wù)。運(yùn)行->cmd輸入->net start msdtc

?

?

?  二、代碼實(shí)現(xiàn)

  

?

  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"/>
????????
<!--自動(dòng)建表(反向映射)-->
????????
<entry?key="hbm2ddl.auto"?value="update"/>
????????
<!--批量更新-->
????????
<entry?key="adonet.batch_size"?value="0"/>
????????
<!--超時(shí)時(shí)間-->
????????
<entry?key="command_timeout"?value="60"/>
????????
<!--啟用二級(jí)緩存-->
????????
<entry?key="cache.use_second_level_cache"?value="false"/>
????????
<!--啟動(dòng)查詢(xún)緩存-->
????????
<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"/>
????????
<!--自動(dòng)建表(反向映射)-->
????????
<entry?key="hbm2ddl.auto"?value="update"/>
????????
<!--批量更新-->
????????
<entry?key="adonet.batch_size"?value="0"/>
????????
<!--超時(shí)時(shí)間-->
????????
<entry?key="command_timeout"?value="60"/>
????????
<!--啟用二級(jí)緩存-->
????????
<entry?key="cache.use_second_level_cache"?value="false"/>
????????
<!--啟動(dòng)查詢(xún)緩存-->
????????
<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?
=?"中國(guó)北京",
????????????????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>

?

?

?

  運(yùn)行結(jié)果如下:

  一、初始化數(shù)據(jù):

  

?

  

?

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

?

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

?

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

?

  五、建立第一個(gè)訂單(插入第四次數(shù)據(jù)),訂金超過(guò)3000

  

?

?

  從運(yùn)行結(jié)果上看到,當(dāng)我們創(chuàng)建第四張訂單時(shí),由于訂金超過(guò)3000后拋出異常,數(shù)據(jù)實(shí)現(xiàn)回滾。這樣分布式事務(wù)便實(shí)現(xiàn)了。

?

  代碼下載

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

  歡迎轉(zhuǎn)載,但需保留版權(quán)。

轉(zhuǎn)載于:https://www.cnblogs.com/GoodHelper/archive/2010/07/29/SpringNetDistributedTransaction1.html

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。