惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
Security Latest
Security Latest
Simon Willison's Weblog
Simon Willison's Weblog
O
OpenAI News
GbyAI
GbyAI
L
LINUX DO - 最新话题
A
Arctic Wolf
T
Tor Project blog
G
GRAHAM CLULEY
I
InfoQ
博客园_首页
IT之家
IT之家
The Register - Security
The Register - Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
The GitHub Blog
The GitHub Blog
Blog — PlanetScale
Blog — PlanetScale
N
Netflix TechBlog - Medium
K
Kaspersky official blog
博客园 - 三生石上(FineUI控件)
S
SegmentFault 最新的问题
U
Unit 42
PCI Perspectives
PCI Perspectives
量子位
P
Palo Alto Networks Blog
S
Securelist
T
Troy Hunt's Blog
博客园 - 【当耐特】
Recorded Future
Recorded Future
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
S
Security Affairs
Engineering at Meta
Engineering at Meta
T
The Blog of Author Tim Ferriss
博客园 - 聂微东
罗磊的独立博客
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
B
Blog RSS Feed
NISL@THU
NISL@THU
C
Cisco Blogs
T
Threatpost
有赞技术团队
有赞技术团队
Forbes - Security
Forbes - Security
Hugging Face - Blog
Hugging Face - Blog
Last Week in AI
Last Week in AI
T
The Exploit Database - CXSecurity.com
Cloudbric
Cloudbric
Cyberwarzone
Cyberwarzone
Google DeepMind News
Google DeepMind News
C
Cyber Attacks, Cyber Crime and Cyber Security

博客园 - jy_kwwl

强烈谴责不负责任的novell OpenSUSE 11.1 任意用户读写NTFS分区的问题解决 Redmine集成Mercurial mysql-connector-net 源代码中有编码导至编译不通过的解决办法 玩手机要留意的黑手: 世界比你想像的黑, 即使不黑, 防人之心不可无. NVIDIA史上最大显卡质量事故,我正在用Vostro 1400 写了四五年代码,居然还会出这样的问题 - jy_kwwl - 博客园 记念0day IP地址或域名对应的主机上开通站点查询工具 个人网站传音石开发段落性总结 一些烦恼锁事 国人对国产软件的几个误区[转载] 世界上最强的中国式英文 记念传音石新版的上线 总结一下SubSonic使用技巧 日本开发出微型燃料电池 尺寸大小似水果糖 饭前饭后的疾病信号 什么是CMM? 什么是数据挖掘?
SubSonic中使用TransactionScope
jy_kwwl · 2007-06-25 · via 博客园 - jy_kwwl

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