来源: 嵌套事务(一):.NET中嵌套事务运用的一点思考_邓福勇-CSDN博客
说实际情形:
由于一个操作中分两步完成,不妨定义为 Method1(),Method2()。只有当一两步都成功执行时,整个操作才算完成,否则要回滚所有数据。
一开始,我的实现思路是:
Operate()
{
创建事务连接,开始事务…..
If(Method1() 成功&& Method2() 成功)
{ 事务执行成功 }
Else
{
事务回滚,执行不成功
}
关闭事务,连接….
}
说明:Method1(),Method2()是独立的方法,里面也是事务。
一开始,想当然的认为没问题,简单测试也没什么问题。
但实际上是有问题的。问题在哪儿呢?
不多说,假设Method1()成功,Method2()失败。会出现什么后果:Operate()
回滚,Method2()回滚,Method1()不回滚(为什么,每个方法内,都new了一个新的事务对象,是独立于外部事务的)。
所以换了一下思路,只有硬来了
Operate()
{
创建事务连接,开始事务…..
//1 将Method1()的实现代码写在这儿
…….
成功(不提交),继续下走;不成功,回滚。
//2 将Method2()的实现代码写在这儿–有问题的(2011-1-17注)
…….
成功(不提交),继续下走;不成功,回滚。
// 3
在这里才确定了整个事务成功。
……
}
所以在.NET 中嵌套事务实现几个动作同时进行时,一定要小心。本文的思路是,将所有的分步操作,在一个事务中实现,也就没了嵌套事务,但实际的结果是一样,并提高了性能。只是以代码的长度作为代价的,呵呵。
当然,有时允许成功了的部分不回滚,那第一种情形也就适用了。
———————————–2011分隔线——————————————–
现在再来看上来的东西,可以改进: 接着讲更实际些的。
1:跨库操作(来源于两个不同的数据库) demo:
SQLConnection connConsDB = dboConsDB.CreateConnection as SQLConnection;
SqlConnection connStatDB = dboStatDB.CreateConnection as SqlConnection;
connConsDB.Open();
connStatDB.Open();
using (SqlTransaction tranConsDB = connConsDB.BeginTransaction())
{
using (SqlTransaction tranStatDB = connStatDB.BeginTransaction())
{
try
{
//ip数据操作
OperatIp(tranConsDB, tranStatDB);
//cookie数据操作
OperatCookie(tranConsDB, tranStatDB);
tranConsDB.Commit();
tranStatDB.Commit();
result.IsSuccess = true;
result.Message = “广告注册用户激活游戏数据操作成功”;
}
catch (Exception ex)
{
exceptionDBLog.InsertExceptionLog(ex);
tranConsDB.Rollback();
tranStatDB.Rollback();
result.IsSuccess = false;
result.Message = “广告注册用户激活游戏数据操作失败”;
}
}
}
2:多步操作为一事务(即我们刚开始讨论的东西)
SqlConnection con = dbo.CreateConnection as SqlConnection;
con.Open();
SqlTransaction tran = con.BeginTransaction();
try
{
//获取数据源
DataResult resultADClickIp = GetADClickIpResult();
DataResult resultRegisterTmp = GetRegisterTmpResult();
DataResult resultRechargeExchangeTmp = GetRechargeExchangeTmpResult();
DataResult resultWenDaoGameActiveTmp = GetWenDaoGameActiveTmp();
DataResult resultMHSSGameActivateTmp = GetMHSSGameActivateTmp();
DataResult resultJDFJGameActivateTmp = GetJDFJGameActivateTmp();
DataResult resultDanGameActivateTmp = GetDanGameActivateTmp();
DataResult resultAdVisitLogTmp = GetAdVisitLog();
DataResult resultPageViewLogTmp = GetPageViewLog();
//转移数据
MoveADClickIpTbl(resultADClickIp, tran);//广告点击IP表(第二层核心数据)[定期转移])
MoveRegisterTmpTbl(resultRegisterTmp, tran); //注册用户临时表(第二层)[保留3个月] 数据
MoveMHSSGameActivateTmpTbl(resultMHSSGameActivateTmp, tran);// 转移**游戏激活日志临
MoveJDFJGameActivateTmpTbl(resultJDFJGameActivateTmp, tran);// 转移**游戏激活日志临时
MoveDanGameActivateTmpTbl(resultDanGameActivateTmp, tran);// 转移**游戏激活日志临时表
MoveAdVisitLogTmpTbl(resultAdVisitLogTmp, tran);//转移广告访问日志数据源
MovePageViewLogTmpTbl(resultPageViewLogTmp, tran);//站点日志部分
tran.Commit();
return true;
}
catch (Exception ex)
{
tran.Rollback();
exceptionDBLog.InsertExceptionLog(ex);
return false;
}
SQLServer 事务相关:《嵌套事务(一):.NET中嵌套事务运用的一点思考》
《嵌套事务(二):SQLServer中嵌套事务使用》
《SqlServer 嵌套事务机制 测试 》
————————————————
版权声明:本文为CSDN博主「xiaoyong322」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dfyong/article/details/5684381