jinyong

平淡生活,努力工作

导航

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修改过的工程下载:https://files.cnblogs.com/jinyong/subsonic2.1.zip



posted on 2007-06-25 10:56  jy_kwwl  阅读(5424)  评论(20编辑  收藏  举报