亚音速中使用的TransactionScope
墨初 知识笔记 35阅读
SubSonic与Rails中的ActiveRecord非常相似。它不仅将代码生成工具集成到IDE中,还可以自行定制模板。虽然还是有问题,但是目前的版本已经可以满足日常的开发了。由于数据库操作被封装,现有的事务处理方法无法满足需求。在此之前,Castle ActiveRecord一直用于开发,它提供的TransactionScope使用起来非常方便。这种转变也得益于Castle ActiveRecord。1.在DataProvider的转换中添加以下代码://jyprotectedpool _ isNeedtransaction=false;protectedDbTransaction _ Transaction;内部的
l 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
}
}
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
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;
}
}
/// 收货处理。
/// </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;
}
}
有更好的改进建议,希望大家交流一下!
SubSonic修改过的工程下载:
标签: