- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我们正在逐步用 Entity Framework (4.3.1) 替换遗留数据访问代码。在某些情况下,我们无法避免在一个工作单元中同时使用两种数据访问方式。理想情况下,这应该在一次交易中完成。但是,旧代码使用 SqlTransaction
,当一个工作单元完成并且 EF 管理自己的事务时调用 Commit()
。
所以我们想到将“旧”和"new"代码包装在 TransactionScope
中.但是,始终执行周围 TransactionScope
中的 Commit,即使 TransactionScope
未完成。此代码片段说明了我的问题:
using (var conn = new SqlConnection("connection string"))
{
conn.Open();
using (var scope = new TransactionScope())
{
using (var tr = conn.BeginTransaction())
{
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = tr;
cmd.CommandText = "some update statement";
cmd.ExecuteNonQuery();
}
tr.Commit();
}
// In reality the code above is part of a legacy DAL, immutable.
// (can't insert SaveChanges before tr.Commit).
context.SaveChanges();
if (<all ok>) // pseudo code for exception handling.
scope.Complete();
}
}
当 scope.Complete()
未命中时,更新语句仍在提交。
看起来,我无法使用 TransactionScope
强制旧数据访问代码和来自上下文的 SaveChanges
在一个事务中执行。 或者有没有办法否决 SqlTransaction.Commit 语句?
我知道这里有更多关于 TransactionScope 和 SqlTransaction 的帖子,但他们都(正确地)说在使用 TransactionScope 时不需要(也不推荐)使用 SqlTransaction。但不使用 SqlTransaction 在这里不是一个选项。我们有一个遗留框架,它提交自己的 SqlTransaction
,并且没有用于挂接到其事务机制的 API。
最佳答案
The update statement is still committed when scope.Complete() is not hit.
哦不!未使用 TransacationScope1。
如果连接在 TransactionScope 之后(或内部)打开,则自动登记仅有效。
将 Open
放在 TransactionScope
应该解决这个问题(即使是手动交易?)作为然后 Connection [通常] 会在环境 TS 上下文中自动登记。
可以将现有连接纳入环境事务范围:connection.EnlistTransaction(Transaction.Current)
。
或者,TS 可以从现有交易中创建,例如new TransactionScope(transaction)
,这在这里可能有帮助也可能没有帮助。
如果完全没问题,则创建手动交易,但 TS(在找出陷阱之后!)使处理交易变得更加简单和容易.. 至少在大多数情况下 :)
编码愉快!
1 TS 未用于“更新语句”。它仍然 [可能] 用于 context.SaveChanges()
,因为这将打开一个新连接,然后自动登记。
虽然我不确定普通的“嵌套”事务,但我在上面提供了一些选项。查看在上下文中使用的(密封的?)API 可能会揭示有关限制/限制的更多见解。
关于c# - 忽略 TransactionScope 中的 SqlTransaction.Commit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11418301/
使用 SQLTransaction 的合适时间是什么时候? 我将它们用于我所有的 INSERT、UPDATE 和 DELETE 语句。 这是正确的用法还是我做得有点矫枉过正? 最佳答案 当您希望以原子
这里有一些背景:我们的站点会定期崩溃,以至于不得不重新启动 IIS;这几乎总是在修补 DLL 后的一个小时内发生(我们使用网站项目,而不是 Web 应用程序项目,因此每个 ASPX 页面都是一个单独的
我的应用程序中有一次出现以下错误。 This SQLTransaction has completed; it is no longer usable Stack Trace 附在下面 – 它说明了
所以我有一个PatientInfo表,我只需点击一个按钮就可以插入一个患者。。同样的按钮会生成患者的ID,但出于某种原因,如果我运行计时器同时从5个应用程序执行此代码,则只有一个应用程序会通过,而其他
所以我有一个PatientInfo表,我只需点击一个按钮就可以插入一个患者。。同样的按钮会生成患者的ID,但出于某种原因,如果我运行计时器同时从5个应用程序执行此代码,则只有一个应用程序会通过,而其他
我需要在 SqlTransaction 的 finally block 中调用 dispose 吗?假装开发人员没有在任何地方使用 USING,然后尝试/捕获。 SqlTransaction sqlT
我们有一个有趣的设置,我们将 SqlTransactions 持久化到 Web 应用程序的应用程序内存中。我们正在考虑将我们的 Web 应用程序移动到 NLB 场景中,因此我们需要一种方法使这些事务不
一旦事务开始,是否可以延长事务的超时(使用 SQL Server)? 最佳答案 超时对于 SQL Server 来说是“外部”的,因此 SQL Server 不会影响它。 不幸的是,“不” 关于.ne
我在此网站上找到了以下引用:“建议您使用 TransactionScope 类创建隐式事务”:http://msdn.microsoft.com/en-us/library/system.transa
我很好奇以下代码是否被认为是安全的? using (SqlConnection cn = new SqlClient.SqlConnection(connectionString)) { cn.
我有一个类,其中包含我的 ASP.NET 4.0 应用程序的所有数据访问代码。类中有两种方法可以将数据插入数据库。我想在 SqlTransaction 中加入这些插入,并在其中一个插入失败时回滚事务。
我有一个循环,我在其中调用具有不同参数值的存储过程。接下来调用 cmd.ExecuteNonQuery();我使用事务来保存全部或回滚,并使用 checkBox2 - 始终保存。我发现了一个问题,但找
前几天研究了SqlTransaction,知道了SqlTransaction.Commit()的用途——应该是“提交数据库事务”。 -MSDN。 但是它是如何工作的? 例如:我写了一段代码是这样的:
我在我的代码中使用 SqlTransaction 来实现回滚目的。在交易中,我得到了多个要执行的语句,可能包括选择插入和更新。所有这些语句都在 sqltransaction 的范围内。一切正常只针对一
我遇到了一个问题,即使没有任何查询引发异常,所做的更改也会被回滚。这很奇怪,因为代码在一个环境中工作但不在另一个环境中提交更改。 这是处理事务的函数。当我在提交上放置一个断点时,我点击了提交,我可以看
我正在尝试以异步方式提交/回滚 SqlTransaction。但看起来不支持异步。有什么方法可以在不使用原始 SQL 启动事务的情况下使其异步? 最佳答案 看起来不像。通过相关代码,所有其他方法都是异
我要开始说我很确定这是不可能的。谷歌搜索没有发现任何人问这个问题,所以我悲观地希望。 我正在使用 SqlTransaction 连接到数据库,并在我关闭它之前允许多个消费者使用该事务。是否可以确定事务
我有两个存储过程,我想在一个事务中执行它们。由于各种原因,我需要在我的应用程序代码中而不是在数据库中处理事务。 目前,我的代码如下所示: try { using (SqlConnection
我有以下使用 SqlTransaction 的代码。我已经在 catch 和 finally block 中调用了 dispose。但是我没有在调用 Dispose() 之前检查它是否已经被处理。我们
所以我有多个 SqlConnections,我希望它们全部用于一个 SqlTransaction。我知道我可以只使用一个连接,但最终在每个连接中都有大量新声明和无用的(连接完成后)变量,我需要程序尽可
我是一名优秀的程序员,十分优秀!