SubSonic中使用TransactionScope

SubSonic使用起来非常像Rails中的ActiveRecord,不仅将代码生成工具集成到了IDE中,而且还可以自己来定制模板。虽然还存在问题,但现在的版本是可以满足日常开发了。

由于把数据库操作封装起来了,因此现有的事务处理方式并不能满足需求,在这之前一直在使用Castle ActiveRecord进行开发,它提供的TransactionScope使用非常方便,这次改造也得益于Castle ActiveRecord

 

一、DataProvider改造

添加如下代码:

         // jy
         protected   bool  _IsNeedTransaction  =   false ;
        
protected  DbTransaction _Transaction;

        
internal   void  BeginShareTransaction()
        {
            
if  (__sharedConnection  ==   null   ||
                __sharedConnection.State 
!=  ConnectionState.Open)
            {
                InitializeSharedConnection();
            }

            _Transaction 
=  __sharedConnection.BeginTransaction();
            _IsNeedTransaction 
=   true ;
        }

        
internal   void  BeginShareTransaction(IsolationLevel level)
        {
            
if  (__sharedConnection  ==   null   ||
                __sharedConnection.State 
!=  ConnectionState.Open)
            {
                InitializeSharedConnection();
            }

            _Transaction 
=  __sharedConnection.BeginTransaction(level);
            _IsNeedTransaction 
=   true ;
        }

        
internal   void  PrcessTransaction( bool  rollback)
        {

            
try
            {
                
if  (_Transaction  !=   null )
                {
                    
if  ( ! rollback)
                    {
                        _Transaction.Commit();
                    }
                    
else
                    {
                        _Transaction.Rollback();
                    }
                }
                
else
                {
                    
throw   new  ApplicationException( " 请先实例化TrancactionScope类启动事务! " );
                }
            }
            
finally
            {
                
if  (__sharedConnection.State  ==  ConnectionState.Open)
                {
                    __sharedConnection.Close();
                }

                __sharedConnection.Dispose();
            }
        }
        
// jy end


 

二、添加TransactionScope类

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Data.Common;
using  System.Data;

namespace  SubSonic
{
    
///   <summary>
    
///  使用共享连接完成事务处理。
    
///   </summary>
     public   class  TransactionScope : IDisposable
    {
        DataProvider _Provider 
=   null ;
        
bool  _IsRollback  =   false ;

        
#region  构造函数
        
///   <summary>
        
///  构造函数,开始事务处理。
        
///   </summary>
         public  TransactionScope()
        {
            _Provider 
=  DataService.GetInstance( null );

            _Provider.BeginShareTransaction();
        }

        
///   <summary>
        
///  构造函数,开始事务处理。
        
///   </summary>
        
///   <param name="level"> 事务级别 </param>
         public  TransactionScope(IsolationLevel level)
        {
            _Provider 
=  DataService.GetInstance( null );

            _Provider.BeginShareTransaction(level);
        }

        
///   <summary>
        
///  构造函数,开始事务处理。
        
///   </summary>
        
///   <param name="ProviderName"> 提供器名称 </param>
         public  TransactionScope( string  ProviderName)
        {
            _Provider 
=  DataService.GetInstance(ProviderName);

            _Provider.BeginShareTransaction();
        }

        
///   <summary>
        
///  构造函数,开始事务处理。
        
///   </summary>
        
///   <param name="ProviderName"> 提供器名称 </param>
        
///   <param name="level"> 事务级别 </param>
         public  TransactionScope( string  ProviderName,IsolationLevel level)
        {
            _Provider 
=  DataService.GetInstance(ProviderName);

            _Provider.BeginShareTransaction(level);
        }
        
#endregion

        
///   <summary>
        
///  标记为提交状态。
        
///   </summary>
         public   void  VoteCommit()
        {
            
if  (_IsRollback)
            {
                
throw   new  ApplicationException( " 当前事务已回滚,不能再进行提交操作! " );
            }
        }

        
///   <summary>
        
///  标记为回滚状态。
        
///   </summary>
         public   void  VoteRollback()
        {
            _IsRollback 
=   true ;
        }

        
#region  IDisposable 成员
        
///   <summary>
        
///  
        
///   </summary>
         public   void  Dispose()
        {
            _Provider.PrcessTransaction(_IsRollback);
        }

        
#endregion
    }
}

三、SqlDataProvider改造

在每一个新建了SqlCommand的地方都添加以下代码:
             // jy
             if  (_IsNeedTransaction)
            {
                cmd.Transaction 
=  _Transaction  as  SqlTransaction;
            }
            
// jy end

其它数据库提供器的也使用相同的方法进行改造。

四、使用示例

     ///   <summary>
    
///  收货处理。
    
///   </summary>
    
///   <param name="id"></param>
    
///   <param name="UserId"></param>
     public   static   void  Receiving( object  id, object  UserId)
    {
        
using  (TransactionScope tran  =   new  TransactionScope())
        {
            
try
            {
                LogiPackage lp 
=   new  LogiPackage(id);

                
string  strSql  =   "" ;
                LogiWarehouse lw 
=   new  LogiWarehouse();
                LogiPackageDetailCollection lpds 
=  lp.LogiPackageDetails();

                
// foreach (LogiPackageDetail d in lpds)
                
// {
                
//     Query q = LogiWarehouse.Query();

                
//     q.AddWhere("Freight_Id", d.FreightId);
                
//      // 检查发送人的库存
                
//     q.AND("Company_Id", lp.SendId);

                
//     lw.LoadAndCloseReader(q.ExecuteReader());

                
//      // if (lw.Count < d.Count)
                
//      // {
                
//      //     throw new ProcessErrorException("库存不足,请检查!");
                
//      // }
                
// }
                



                
foreach  (LogiPackageDetail d  in  lpds)
                {
                    Add(lp.InceptId, d.FreightId, d.Count);
                    Dec(lp.SendId, d.FreightId, d.Count);
                }

                LogiPackageStatus lps 
=   new  LogiPackageStatus( " Code " 3 );

                lp.StatuId 
=  lps.Id;

                lp.Save();

                Log(
new  Guid(UserId.ToString()), lps.Id, lp.Id);

                tran.VoteCommit();
            }
            
catch
            {
                tran.VoteRollback();
                
throw ;
            }
        }


目前已成功在http://www.massany.com和帮朋友做的一个物流系统中使用。

有更好的改进建议,希望大家交流一下!

 

SubSonic修改过的工程下载: http://files.cnblogs.com/jinyong/subsonic2.1.zip



转载于:https://www.cnblogs.com/jinyong/archive/2007/06/25/794650.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值