Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从Excel VBA启动TransactionScope?_C#_Sql Server_Vba_Excel_Com Interop - Fatal编程技术网

C# 从Excel VBA启动TransactionScope?

C# 从Excel VBA启动TransactionScope?,c#,sql-server,vba,excel,com-interop,C#,Sql Server,Vba,Excel,Com Interop,我有一些现有的c代码,我想通过com互操作公开这些代码,以便可以从Excel VBA调用它们。由于我将执行许多嵌套的批处理更新操作,我需要支持事务,并且为了最大限度地减少c级所需的重构,我希望使用TransactionScope方法: 使用事务作用域实现隐式事务 TransactionScope类提供了一种简单的方法来标记数据块 编码为参与交易,无需您 与事务本身交互。可以选择一个事务范围 并自动管理环境事务。由于其易于操作 使用和效率,建议您使用 在开发事务应用程序时使用Transactio

我有一些现有的c代码,我想通过com互操作公开这些代码,以便可以从Excel VBA调用它们。由于我将执行许多嵌套的批处理更新操作,我需要支持事务,并且为了最大限度地减少c级所需的重构,我希望使用TransactionScope方法:

使用事务作用域实现隐式事务

TransactionScope类提供了一种简单的方法来标记数据块 编码为参与交易,无需您 与事务本身交互。可以选择一个事务范围 并自动管理环境事务。由于其易于操作 使用和效率,建议您使用 在开发事务应用程序时使用TransactionScope类

此外,您不需要使用 交易任何系统事务资源管理器,如SQL Server 2005可以检测到环境事务的存在 由作用域创建并自动登记


我的问题是:是否可以在VBA代码中启动TransactionScope或通过COM interop调用c方法来实例化并返回TransactionScope对象,然后通过COM interop继续调用其他各种c对象,哪些将自动参与单根事务?

我认为您的方法没有问题。您没有在VBA中使用,因此必须通过

使用错误处理程序和 非常小心不要在没有以某种方式处理TransactionScope的情况下离开该方法。 例如,假设在C应用程序中,您提供以下方法:

public TransactionScope BeginTransactionScope()
{
    return new TransactionScope();
}

public void CommitTransactionScope(TransactionScope scope)
{
    scope.Complete();
    scope.Dispose();  // simulates leaving the using { ... } scope
}

public void RollbackTransactionScope(TransactionScope scope)
{
    scope.Dispose();  // simulates leaving the using { ... } scope
}

// Does some work using Connections and maybe nested scopes
public void DoSomeWork1() { ... }
public void DoSomeWork2() { ... }
public void DoSomeWork3() { ... }
编译C DLL并通过COM互操作将其提供给Excel VBA。在VBA中,可以按如下方式运行方法:

Private Sub MySub()

    On Error Goto MyErrorHandler

    ...
    Dim scope As Object
    Set scope = myCsObject.BeginTransactionScope()
    ...
    myCsObject.DoSomeWork1
    ...
    myCsObject.DoSomeWork2
    ...
    myCsObject.DoSomeWork3
    ...
    myCsObject.CommitTransactionScope scope
    Set scope = Nothing
    ...

    Exit Sub

MyErrorHandler:
    If Not (scope Is Nothing) Then
        myCsObject.RollbackTransactionScope scope
    End If
    ' Remainder of your error handler goes here
    ...
End Sub

但是请注意,在DoSomeWork调用之间使用VBA代码执行的任何数据访问都将超出事务范围,因为TransactionScope与经典ADO或DAO不兼容。

No,你绝对不能在VBA中这样做。你能详细说明一下吗?我希望我不是要你证明一个否定的答案。我删除了我的答案,因为我认为我们不在同一页上理解C的事务范围是什么以及VBA中的事务范围是什么。ADODB实现了在事务期间回滚任何更改的机制,但是如果事务失败,您不能将任何VBA代码块包装在TransactionScope中并使其回滚…很抱歉,我可能误解了这里的某些内容,但这一切的意义是什么,因为如果您使用C来处理事务,并且从VBA显式调用它。您也可以用C处理整个事务过程,只需使用一个方法返回结果即可。为什么要将它全部暴露在VBA中,因为它可以从C轻松处理?@mehow:1。谢谢你发现错误,修正了。2.也许他需要在各种DoSomeWork调用之间执行VBA代码?无论如何,这是一个好问题,但它可能更好地针对OP而不是我。是的,你没有在VBA中使用,但你有结束。它的工作方式与在C中使用不同,但我想它们之间有某种关联。我想说的是,您不能在VBA中设置TransactionScope,因为VBA使用VB6虚拟机作为运行时,如果有任何意义,它不允许您回滚自己的代码。抱歉,很难解释。@mehow:True,using和With的相似之处在于它们都创建了某种作用域,但在其作用域的末尾使用Dispose调用,而With仅提供访问字段和方法的词法快捷方式。是,但是您可以创建一个实现IDispose的自定义类,当对象的所有引用都是免费的时,它最终将被调用VBA使用引用计数,而您可以为原始TransactionScope创建自己的TransactionScope类包装的实例,但不幸的是System.TransactionScope不是COM看得见的