我有多个客户端通过不可靠的(无线/ gprs)网络连接到SQL Server,并在几分钟内执行大量的小型查询和插入操作。 如果在此过程中网络连接断开,则整个事务将回滚并需要重新启动。 由于业务需求,流程必须是事务性的(即,其他客户只能从其他客户那里看到完整的数据集,或者根本看不到它)。

我希望能够检测到何时断开连接,并能够重新连接到SQL Server,并刚刚删除的同一事务中继续进行处理并避免从头开始重新启动。 目前,我在打开连接后立即使用sp_getbindtoken ,将CommandTimeout设置为较小的值(比TCP KeepAlive小得多),如果在ExecuteNonQuery期间超时,则打开与服务器的新连接,并从进程开始用令牌调用sp_bindsession 然后,我使用与会话绑定到上一流程的事务的新连接继续流程。

到目前为止,它几乎可以完美运行,但是据MSDN称 ,该API已被弃用,并将在以后的SQL Server版本中删除。 问题是:如果没有这两个命令,如何获得相同的结果? 还有其他方法可以从断开的TCP连接中恢复事务吗?

编辑/进一步信息:客户端应用程序在带有条形码扫描仪的Windows CE设备上运行。 我同时提供设备和软件,因此我可以随意放置任何需要的东西。 DB由第三方托管在受保护的环境中,我和客户都无法控制它。 我总共要发送约50MB的每日销售数据。 我可以使用SP来保存数据,但是仍然必须传输它,并且使用一个大参数对SP的一次调用在GPRS / EDGE链路上成功的可能性接近0%。

由于整个解决方案都在生产环境中工作,因此我希望将更改降至最低。 具有与sp_bindsession相同语义的替代API将是完美的。

===============>>#1 票数:2

我只是不购买单笔交易需要约50MB的每日销售数据。 我认为,个别销售交易需要用sql-transaction进行包装,但每个交易都更像1K。 您确定不能在存储过程中在服务器上运行几个小事务吗? 如果每个设备都必须是全部或全部,则可以通过小型事务将设备加载到登台表。 设备完成后,在事务中使用服务器上的存储过程刷新登台表。 或仅在完成上传上放一个布尔列,然后在上传完成后在一次更新中翻转该标志。 50MB的事务确实会锤击事务日志并锁定其他更新。

===============>>#2 票数:0

您提供的MSDN链接建议使用MARS 根据这篇文章:

MARS允许将一个连接用于读取操作和数据操作语言(DML)操作,其中有多个挂起操作。 此功能消除了应用程序处理连接繁忙错误的需要。 此外,MARS可以代替服务器端游标的用户,后者通常会消耗更多资源。 最后,由于多个操作可以在单个连接上进行操作,因此它们可以共享同一事务上下文,从而无需使用sp_getbindtoken和sp_bindsession系统存储过程。

这样,您可以使用BeginTrasaction,除非明确提交,否则事务将自动回滚。 您可以捕获commit语句的失败,然后递归地尝试重新提交它,直到事务的提交成功返回为止。 只是一个主意。 也许是这样的:

private static void ExecuteSqlTransaction(string connectionString)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();

        SqlCommand command = connection.CreateCommand();
        SqlTransaction transaction;

        // Start a local transaction.
        transaction = connection.BeginTransaction("SampleTransaction");

        // Must assign both transaction object and connection
        // to Command object for a pending local transaction
        command.Connection = connection;
        command.Transaction = transaction;

        try
        {
            command.CommandText =
                "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
            command.ExecuteNonQuery();
            command.CommandText =
                "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')";
            command.ExecuteNonQuery();

            // Attempt to commit the transaction.
            transaction.Commit();
            //Both records are written to database.
        }
        catch (Exception ex)
        {
            // Attempt to roll back the transaction.
            try
            {
                transaction.Rollback();
            }
            catch (Exception ex2)
            {
                // This catch block will handle any errors that may have occurred
                // on the server that would cause the rollback to fail, such as
                // a closed connection.
                ExecuteSqlTransaction(connectionString);
            }
        }
    }
}

  ask by MagnatLU translate from so

未解决问题?本站智能推荐:

2回复

SQL事务报告/状态

我一直在寻找一种方法来获取有关已完成的SQL事务的信息。 由于我使用C#连接到数据库,因此我想知道在特定事务期间有多少记录被更新,插入或删除。 有没有办法做到这一点? 提前致谢
1回复

根据计算机名称T-SQL返回IP地址的功能

我在sql server中有一个表,其中包含域中计算机的列表。 它有一个称为FQDN的列,其中包含计算机的名称。 我添加了IP列作为nvarchar (稍后将对其进行格式化)。 我想知道是否可以创建一个函数来根据名称列中的名称从dns获取它们,而不是手动填充ip。 例如在powershe
1回复

是否可以在.net的同一事务中并行运行多个SQL语句?

我想upsert到SQL Server中的7个表。 我首先将SqlBulkCopy分成7个临时表,然后将它们合并到真实表中。 我需要它更快,所以我想知道是否有一种方法可以在同一个事务中并行运行这些,因为如果有任何失败我想要回滚所有这些。 谢谢
2回复

在SQL中重新创建.NET舍入行为

我正在尝试将一个微妙的计算从C#.NET迁移到TSQL,并且绝对每个结果必须保持不变,无论原始C#.NET答案在某些情况下是否不准确。 我的TSQL脚本大多数都是成功的,然而,在.NET中有一些我不能捕获的不寻常的舍入行为。 我将用两个例子来证明: 这是我正在尝试重新创建的.NET
1回复

UPDATE使用旧值后,使用CASE进行SELECT

我有一个由实体框架生成的sql语句组合的问题。 看起来在更新语句完成并且执行选择之后,并没有立即设置powerloss字段的更新值。 我不知道那是否有可能。 也许我只是想念一些东西。 代码执行后,更新和选定的行以及表中的数据是正确的。 它应该做什么(99%的时间都可以做
1回复

SQL-如何在没有多个子选择的情况下比较更改的列值

我正在写一个TSQL查询。 我有下表,其中A列和B列会偶尔更改。 我对与上一行相比(或当previos行不存在时,即第一行)发生变化的每一行都感兴趣。 每个日期将始终是唯一的。 在这种情况下,结果应为: 由于我们对A或B发生变化的第一行感兴趣。 我有一个非常丑陋和
5回复

使用(var connection = new SqlConnection(“ ConnectionString”))是否仍会关闭/将连接置于错误状态?

我有以下代码 问题是:如果using方括号( { } )之间发生意外错误, var connection是否仍会关闭? 问题是我对存储过程的大多数调用都是以这种方式进行的,最近我一直收到此错误: System.InvalidOperationException:超时已过期
4回复

SQLConnection中的参数无效

我有一个连接到数据库的.NET应用程序。 在我的web.config文件中 用户名和密码已删除。 在我的代码后面,我打开这样的连接 我收到的错误是 “System.Data.SQLClient.SQLConnection.SQLConnection(stri
4回复

这将如何使用带有回滚事务的循环来影响数据

此存储过程每天都使用调度程序运行,并且数据通过网络传递。 当此存储过程执行时,然后沿着执行过程突然出现网络超时。 这将执行每一行以通过网络发送到其他服务器。 现在,我的问题是: 这将如何影响在循环内调用回滚事务的数据? 它会再次读取所有行并将其发送到服务器进行
5回复

如何在没有事务初始化的SqlCommand / SqlConnection上设置隔离级别

以下方法应该在打开的连接上执行脏读。 没有交易。 在哪里设置IsolationLevel?