01-07-01【Nhibernate (版本3.3.1.4000) 出入江湖】並發控制

來源:互聯網
上載者:User

標籤:c   style   class   blog   code   java   

Nhibernate 並發控制

【1】封閉式並行存取控制

       正在使用資料的操作,加上鎖,使用完後解鎖釋放資源。

使用情境:資料競爭激烈,鎖的成本低於復原事務的成本

缺點:阻塞,可能死結

【2】開放式並行存取控制:

       所謂樂觀,就是樂觀的認為其他人沒有在用該資源,資源的使用者不加鎖。

      A 讀取資料後,如果該資料被別人B修改,產生錯誤,A復原事務並重新開始。

使用情境:資料競爭不激烈,復原事務的成本低於鎖的成本。

 

-----------------------------------------------------------------------------------------------------------

Nhibernate 支援開放式並行存取控制:

  通過使用<version>或<timestamp>,節點配置。

  注意: <version>要配置一定在<Id>節點之後。否則拋出配置錯誤。如下所示:

Customer.hbm.xmml

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"                    namespace="Model"                    assembly="Model"                     default-lazy="true">    <class name="Model.Customer, Model"         table="Customer"         discriminator-value="0" lazy="false">    <!--unsaved-value="0" 主鍵表中不需要定義,而是需要在子表中定義-->    <id name="CustomerId"        column="CustomerId"        type="int"         unsaved-value="0">      <generator class="native" />      <!-- unsaved-value used to be null and generator was increment in h2.0.3 -->    </id>    <!--version標籤必須放在Id後面,否則出錯-->    <version name="Version"/>
......

 

Order.hbm.xml

  <class name="Model.Order, Model"          table ="[Order]"         discriminator-value="0" lazy="true">    <id name="OrderId"        column="OrderId"        type="int"         unsaved-value="0"> <!--     unsaved-value="0">-->      <generator class="native" />      <!-- unsaved-value used to be null and generator was increment in h2.0.3 -->    </id>        <!--version標籤必須放在Id後面,否則出錯-->    <version name="Version"/>

-------------------------------------------------------------------

 

使用<version>標籤 配置,實現並發控制。

   原理:檢查資料庫的Version欄位的版本值:插入前檢查本身攜帶的Version是否等於現在資料庫的Version值,如果

    【1】相等,插入成功,並且Vesion加儲存帶資料庫。

    【2】不相等,插入失敗,並且拋出NHibernate.StaleObjectStateException類型異常,拋異常:所以並不需要Nhibernate事務的支援,用來復原事務,因為根本就沒插入。

                    

 

   -------------------------------------更新(Update)並發測試------------------------------------------

 

Customer更新(Update)並發測試:

 

       [TestMethod]       [ExpectedException(typeof(NHibernate.StaleObjectStateException))]       public void TestVessionByUpdate()       {           CustomerService customerService = new CustomerService();           OrderService orderService = new OrderService();           Customer customer = new Customer()           {               FirstName = "Test",               LastName = "TestVessionByUpdate",               Age = 10           };           customerService.Add(customer);           Customer customer1 = customerService.Get(customer.CustomerId);           Customer customer2 = customerService.Get(customer.CustomerId);           string customer1Name = "customer1";           customer1.FirstName = customer1Name;           customer2.FirstName = "customer2Test";           customerService.Update(customer2);  //能儲存到資料庫,Customer的version加1           customerService.Update(customer1);  //拋出異常NHibernate.StaleObjectStateException,更新失敗。
 }

 

Order更新(Update)並發測試:

       [TestMethod]       [ExpectedException(typeof(NHibernate.StaleObjectStateException))]       public void TestVessionOrderByUpdateCustomer()       {           CustomerService customerService = new CustomerService();           OrderService orderService = new OrderService();           Customer customer = new Customer()           {               FirstName = "Test",               LastName = "TestVessionOrderByUpdateCustomer",               Age = 10           };           Order order1 = new Order()           {               OrderDate = DateTime.Now.AddMinutes(1),               Customer = customer           };           customer.Orders.Add(order1);           customerService.Add(customer);           Customer customer1 = customerService.Get(customer.CustomerId);           Customer customer2 = customerService.Get(customer.CustomerId);           customer1.Orders.First<Order>().OrderDate = customer1.Orders.First<Order>().OrderDate.AddDays(1);           customer2.Orders.First<Order>().OrderDate = customer2.Orders.First<Order>().OrderDate.AddYears(1);
           customerService.Update(customer2);  //Customer和Order都能儲存到資料庫,Order的version加1           customerService.Update(customer1);  //拋出異常NHibernate.StaleObjectStateException,更新失敗。
}

 

 注意:

        注意已經把已經事務的相關代碼注釋掉了是為說明上面的並發控制並不需要事務的支援。Upadate的代碼如下:

        public void Update(Customer customer)        {            ISession session = _sessionManager.GetSession();            //ITransaction transaction = session.BeginTransaction();            try            {                session.Update(customer);                session.Flush();                //transaction.Commit();            }            catch (Exception)            {                //transaction.Rollback();                throw;            }            finally            {                session.Close();            }        }

 

    -------------------------------------刪除(Update)並發測試------------------------------------------

如果啟用了並發(即配置中添加了<version>標籤屬性),

那麼刪除的時候產生的SQL的Where語句會額外添加一個判斷條件

           where customer.Version = 資料庫裡.vesesion

 

測試代碼:

       [TestMethod]       [ExpectedException(typeof(NHibernate.StaleObjectStateException))]       public void TestVessionDeleteCustomer()       {           CustomerService customerService = new CustomerService();           OrderService orderService = new OrderService();           Customer customer = new Customer()           {               FirstName = "Test",               LastName = "TestVessionDeleteCustomer",               Age = 10           };           customerService.Add(customer);           Assert.IsNotNull(customerService.Get(customer.CustomerId));           Customer customer1 = customerService.Get(customer.CustomerId);           Customer customer2 = customerService.Get(customer.CustomerId);           customerService.Delete(customer1);           customerService.Delete(customer2);       }

 

如所示:

 

 

如果並發刪除同一條記錄,會拋出NHibernate.StaleObjectStateException 類型的異常。

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.