Spring.NET 1.3.2 integrates NHibernate 3.2 – 5 – transaction management

Of course, data access involves transaction management. For NHibernate, we usually use the following method.

//Create a new company
var session = Assyria.DataAccess.SessionFactory.GetCurrentSession();
using (NHibernate.ITransaction transaction = session.BeginTransaction())
{
    session.Save(company);
    transaction.Commit();

}

The session’s BeginTransaction is used to start transaction management, and the Commit method is used to explicitly commit the transaction.

Spring.NET provides complete support for transaction management, especially the integration with NHibernate, which is very convenient.

First, Spring.NET provides Spring.Data.NHibernate.LocalSessionFactoryObject as a session factory object in assembly Spring.Data.NHibernate32. Then, Nhibernate’s transaction management is implemented through Spring.Data.NHibernate.HibernateTransactionManager provided in Spring.Data.NHibernate32.

Support for specific transactions can be achieved through features.

<tx:attribute-driven transaction-manager="transactionManager"/>

In this way, the configuration file for data access generally looks like the following.



  
  
    Data access configuration information
    Includes: DbProvider
          NHibernate
          Exception handling
          transaction processing
  
 
  
  
    
  

  
  

  

  
  

    
    

    
    
      
        Forbetter.Domain
      
    

    
    
      
        
        
        
        
      
    

    
    

  

  
  
  
    
    
  

  
  
  <tx:attribute-driven transaction-manager="transactionManager"/>

  
  

  

In the code, just declare the required transactions through the transaction characteristics. This feature is defined under the Spring.Transaction.Interceptor namespace and is named Transaction.

Transaction propagation and isolation can be declared through Transaction.

There are seven types of transaction propagation behaviors, which are defined in the Spring.Transaction.TransactionPropagation enumeration and can be declared through the TransactionPropagation attribute of the transaction attribute. Default is TransactionPropagation.Required.

  • REQUIRED: Supports the current transaction. If there is no current transaction, create a new transaction. This is the most common choice.
  • SUPPORTS: Supports the current transaction. If there is no transaction currently, it will be executed in a non-transactional manner.
  • MANDATORY: supports the current transaction, if there is no current transaction, an exception will be thrown.
  • REQUIRES_NEW: Create a new transaction. If a transaction currently exists, suspend the current transaction.
  • NOT_SUPPORTED: Perform operations in a non-transactional manner. If a transaction currently exists, suspend the current transaction.
  • NEVER: Execute in a non-transactional manner and throw an exception if a transaction currently exists.

There are seven types of isolation, which can be declared through the IsolationLevel of the transaction label. Default is IsolationLevel.ReadCommitted.

  • Chaos: Unable to overwrite pending changes in transactions with higher isolation levels.
  • ReadCommitted: A shared lock is held while the data is being read to avoid dirty reads, but the data can be changed before the transaction ends, resulting in non-repeatable reads or phantom data.
  • ReadUncommitted: Dirty reading is possible, which means that shared locks are not issued and exclusive locks are not accepted.
  • RepeatableRead: Places a lock on all data used in the query to prevent other users from updating this data. Prevents non-repeatable reads, but can still have phantom rows.
  • Serializable: Place a range lock on the System.Data.DataSet to prevent rows from being updated or inserted into the dataset by other users until the transaction is completed.
  • Snapshot: Reduces blocking by storing a version of the same data that another application can read while one application is modifying the data. Indicates that you cannot see changes made in other transactions from one transaction, even if you requery.
  • Unspecified: An isolation level different from the specified isolation level is being used, but the level cannot be determined.

The ReadOnly attribute is used to set whether the transaction is read-only. The default is false. for read/write.

NoRollbackFor and RollbackFor are used to set the rollback strategy of the transaction, respectively, to set which exceptions do not need to be rolled back and which exceptions need to be rolled back. The default is that any exception causes a rollback.

How to use it is as follows.

public class FulfillmentService : IFulfillmentService
{
    // fields and properties for dao object omitted, see above
    [Transaction(ReadOnly = false)]
    public void ProcessCustomer(string customerId)
    {
        //Find all orders for customer
        Customer customer = CustomerDao.FindById(customerId);
        foreach (Order order in customer.Orders)
        {
            //Validate Order
            Validate(order);
            //Ship with external shipping service
            ShippingService.ShipOrder(order);
            //Update shipping date
            order.ShippedDate = DateTime.Now;
            //Update shipment date
            OrderDao.SaveOrUpdate(order);
            //Other operations...Decrease product quantity... etc
        }
    }
}

If you don’t like using attributes to annotate transactions, the transaction proxy provided by Spring.NET for NHibernate is TransactionProxyFactoryObject. You can also use the following configuration method to replace the attribute.

<object id="TxProxyConfigurationTemplate" abstract="true" type="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data">
  <property name="PlatformTransactionManager" ref="HibernateTransactionManager"/>
  <property name="TransactionAttributes">
    <name-values>
      <!-- Add common methods across your services here -->
      <add key="Process*" value="PROPAGATION_REQUIRED"/>
    </name-values>
  </property>
</object>

Note that there are some changes in the writing method. The prefix PROPAGATION_ is added to the propagation of transactions.

syntaxbug.com © 2021 All Rights Reserved.