数据库事务,不想把事务当成参数传进去。求解。

he036002 2016-06-03 10:59:35
网上找了一些资料。没想到需要的。解决这个问题的过程如下:
解决方案1:

public void Execute() {
using (SqlConnection connnection = new SqlConnection(DAOExecute.DBConnection)) {
connnection.Open();
SqlTransaction trans = connnection.BeginTransaction();
Execute1(trans);
Execute2(trans);
trans.Commit();
}
}

private void Execute1(SqlTransaction trans) {
//trans 在 TODO
}
private void Execute2(SqlTransaction trans) {
//trans 在 TODO
}


例子中,Execute1和Execute2方法中都有数据库方面的操作,用的连接都是传进去的Trans
把这个事务或者把连接当成参数传来传去可以解决问题。但觉得不是好的方案。于是出现了第二套方案
第二套方案:

public void Execute() {
using (TransactionScope scope = new TransactionScope())
{
Execute1();
Execute2();
scope.Complete();
}
}
private void Execute1()
{
//trans 在 TODO
}
private void Execute2()
{
//trans 在 TODO
}

但是要用TransactionScope类,需要开户MSDCT服务(Distributed Transaction Coordinator)。默认情况下这个服务是不开户的。
有没有类似第二个解决方案的,但又不需要额外设置的方法呢

分少,有多少给多少
...全文
288 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
he036002 2016-06-13
  • 打赏
  • 举报
回复
引用 7 楼 sp1234 的回复:
比如说我们的 BLL 层代码就是针对 MongoDB 数据库驱动来编程的,我们没有去过多考虑什么“跨数据库编程”之类的问题,因为那不值钱。 假设你需要现在考虑什么“事务”,请问你现在有能力脱离了底层数据库机制来设计一套“事务”架构吗?反正我是没有这个能力。如果你打开看 TransactionScope 的源代码,你都会看到它内部有多少内涵?你会看到它其实底层是“空的”,业务中的事务操作、一切都让你来编程实现,而它只是提供一个两阶段提交的简单方案接口操作。只不过当你使用的是SQL Server的 ADO.NET 驱动时,并且是单个数据库操作(并非分布式)时,它又在底层偷换地改为直接使用 DbTransaction。实际上使用 TransactionScope 跟直截了当地使用 SqlTrsansaction 在编程能力上没有什么两样,因为 TransactionScope 并没有提供除了 SqlTrsansaction 以外的什么新的能力,而只是一个更大的“帽子戏法”而实际上帽子里并没有东西。 然而你认为必须沿着 TransactionScope 走不通的路继续走下去,而我认为应该回头。 回头是岸,回头就可以落地。时势比人强,要把精力放到能落地的那些框架设计上。承认“在业务逻辑层必定要直接操作DAL层接口概念”。你如果在业务逻辑层有一个“事务”的概念,要么你能现在就落实在某一种或者几种数据库DAL驱动的通用机制上,要么你就是在业务逻辑上说的事务(例如娶了老婆之后,只有办了合法离婚才可能再合法娶另外一个老婆)。不可能有空中楼阁式的讨论结果。
好吧,在找到更好的方法前先这么着。
  • 打赏
  • 举报
回复
比如说我们的 BLL 层代码就是针对 MongoDB 数据库驱动来编程的,我们没有去过多考虑什么“跨数据库编程”之类的问题,因为那不值钱。 假设你需要现在考虑什么“事务”,请问你现在有能力脱离了底层数据库机制来设计一套“事务”架构吗?反正我是没有这个能力。如果你打开看 TransactionScope 的源代码,你都会看到它内部有多少内涵?你会看到它其实底层是“空的”,业务中的事务操作、一切都让你来编程实现,而它只是提供一个两阶段提交的简单方案接口操作。只不过当你使用的是SQL Server的 ADO.NET 驱动时,并且是单个数据库操作(并非分布式)时,它又在底层偷换地改为直接使用 DbTransaction。实际上使用 TransactionScope 跟直截了当地使用 SqlTrsansaction 在编程能力上没有什么两样,因为 TransactionScope 并没有提供除了 SqlTrsansaction 以外的什么新的能力,而只是一个更大的“帽子戏法”而实际上帽子里并没有东西。 然而你认为必须沿着 TransactionScope 走不通的路继续走下去,而我认为应该回头。 回头是岸,回头就可以落地。时势比人强,要把精力放到能落地的那些框架设计上。承认“在业务逻辑层必定要直接操作DAL层接口概念”。你如果在业务逻辑层有一个“事务”的概念,要么你能现在就落实在某一种或者几种数据库DAL驱动的通用机制上,要么你就是在业务逻辑上说的事务(例如娶了老婆之后,只有办了合法离婚才可能再合法娶另外一个老婆)。不可能有空中楼阁式的讨论结果。
  • 打赏
  • 举报
回复
TransactionScope 没有什么意义,它其实就是在存在一个全局静态变量,在 SqlConnection 创建时会去搜索当前线程有没有这样一个变量来传送一个 DBTransaction,如果有则自动会使用这样一个 Transaction,这就省得你自己传递一个 DbTransaction 作为参数了。 TransactionScope 就是省得你在 Execute1() 和 Execute2() 的参数上设计 DbTransaction 参数,而是自动用一个“全局的参数”。那么这叫做“好的方案”吗?这叫做自欺欺人方案。因为你还是得默认地知道你需要维护数据库事务,而且知道哪一个事务必须在调用 Execute1() 和 Execute2() 之前(之外)。 实际上我最讨厌自欺欺人的接口设计。我比较喜欢第一种形式,而不是第二种。 回到你的问题,假设你要一种超脱于 DAL 的事务,那么你就应该先说明白你如何“造空中楼阁”。如果你有本事在200的空中造一座东方明珠电视塔,其底座距离地面200米,中间没有任何支撑,那么我相信你就能完成这个程序架构需求。 当你在业务逻辑层去讨论“我要调用Execute1()、然后调用Execute2()”的时候,请问你如何“只用”业务逻辑层概念来定义“事务”这个概念?你需要在业务逻辑层定义一种空中楼阁式的、世界上至少20种最后最流行的DAL都兼容的“事务概念”。如果你能定义出来,并且经过实践检验,那么你就可以把这个作为你的业务逻辑层的概念。 但是这也还是“落地了”。所以编程中的任何事务概念,都需要脚踏实地。而使用 SqlTransaction trans 或者 DbTransaction trans 作为参数并没有什么问题,大不了你在5年之后找到了上述的“可以兼容20种流行DAL系统”的事务时再来重构你的代码就好了。 所以编程,不是洁癖,而是工程实践。如果你在最近1年根本不可能重构,就不要追求过度的技术。
秋的红果实 2016-06-12
  • 打赏
  • 举报
回复
如果Execute1和Execute2代码不是很多,复用性也不高的话,就直接写代码,不要调用方法了 如果必须要调用方法,那就传递事务吧
he036002 2016-06-12
  • 打赏
  • 举报
回复
我描述的这么清晰,大神们给个答复。
he036002 2016-06-03
  • 打赏
  • 举报
回复
引用 1 楼 starfd 的回复:
zookeeper,可以做分布式锁,但并没什么卵用,你何苦为了个不传而越弄越复杂呢
我是头一次写这方面的代码。以前写CS架构的软件,是一个长连接。把数据库连接那里封装好后不管就行了,觉得很省事。在代码方面也想简洁一些,达到同样的效果。当然,如果没其它办法,最后也会用第一种,把连接当成参数,让它飞来飞去了。
  • 打赏
  • 举报
回复
zookeeper,可以做分布式锁,但并没什么卵用,你何苦为了个不传而越弄越复杂呢
还想懒够 2016-06-03
  • 打赏
  • 举报
回复
TransactionScope方便一些,就只是开启一个MSDTC而已,这没啥难度吧

62,270

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧