技术开发 频道

.NET实用技巧—NHibernate分布式事务

      【IT168 技术应用】我们已实现了在同一应用程序下的分布式事务——即多Dao层+同Service层,每个Dao对应一个数据库,一个Service调用多个Dao。但是在一些特定的子系统较多的项目中,开发人员是无法访问到某个子系统的数据库,这就意味着不能通过增加Dao层来实现分布式事务。正如一个银行的软件系统,记录了客户的账户信息和存款金额,北京的分公司和上海的分公司分别有自己的数据库和软件系统。现在,要实现北京的系统向上海的系统转账,然而各自作为开发人员来说,没有足够的权限去访问对方的数据库,但是可以提供Web Service的方式去访问其系统服务。这样,我们就需要实现基于Web Service的分布式事务。

  实现基于Web Service的分布式事务的方法比较多,可以通过.NET企业服务的方式。但是为了更好的实现,我们选择WCF作为一个分布式应用程序框架。WCF在实现分布式事务中有它的优越之处。其思路在于启动MSDTC服务,将客户端的事务以流的方式传递到服务器端,在服务器端执行通过时,客户端再提交事务,相反则回滚事务。

  我们模仿上篇的场景做一个demo,并使用上篇的Dao和Domain。

  一、启动MSDTC服务。

  二、Service层

  ①.Customer

  public interface ICustomerManager
    {
        CustomerInfo
Get(object id);

        
object Save(CustomerInfo entity);

        void Update(CustomerInfo entity);
    }

    
public class CustomerManager : ICustomerManager
    {
        
private ICustomerDao Dao { get; set; }

        
public CustomerInfo Get(object id)
        {
            return Dao.Get(id);
        }

        
public object Save(CustomerInfo entity)
        {
            return Dao.Save(entity);
        }

        
public void Update(CustomerInfo entity)
        {
            
if (entity.Money > 3000)
            {
                throw
new Exception("订金上限");
            }
            Dao.Update(entity);
        }
    }
<?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

  public interface IOrderManager
    {
        
object Save(OrderInfo entity);
    }

    
public class OrderManager : IOrderManager
    {
        
public IOrderDao Dao { get; set; }

        
public object Save(OrderInfo entity)
        {
            return Dao.Save(entity);
        }
    }
<?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>

0
相关文章