首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过SSIS在Ingres连接上设置LOCKMODE会话= MVCC

如何通过SSIS在Ingres连接上设置LOCKMODE会话= MVCC
EN

Stack Overflow用户
提问于 2015-07-27 03:32:35
回答 2查看 778关注 0票数 2

请任何人提供关于如何从SSIS?登记MVCC会话的建议吗?

从Ingres读取时,我们需要启用MVCC,并在SSIS 2008 R2包中指定隔离级别。

该数据库上存在一个不使用MVCC的现有应用程序,因此在现有DBMS上启用MVCC是不合适的。我们希望读入MVCC中的原因是确保我们不会导致锁并破坏现有的应用程序(就像当前不使用MVCC执行这些读取时周期性发生的那样)。

DB版本是Ingres II 10.0.0 (su9.us5/132)

ADO.NET驱动程序版本是Ingres.Client.IngresConnection, Ingres.Client, Version=2.1.0.0驱动程序,

我们有一个类似的要求,从Tibco BusinessWorks内部以编程方式这样做,并通过例如Squirrel进行交互,并通过直接执行(通过JDBC)发出以下命令来满足这一需求:

代码语言:javascript
复制
SET LOCKMODE SESSION WHERE LEVEL = MVCC;
SET SESSION ISOLATION LEVEL READ COMMITTED;    

在SSIS中,我们可以使用任务/序列的IsolationLevel属性设置会话隔离级别。但是我找不到直接发出MVCC命令的方法。

我试图通过Exceute SQL Task步骤发出命令,但遇到以下错误:

第1行语法错误。最后一次符号读取是:“设置LOCKMODE”。

我所做的一切,都没有结果:

  • 带或不带终止的;
  • 在序列的内部或外部执行步骤
  • 在序列和步骤级别上启用DelayValidation属性
  • 顺序和任务级别上的各种TransactionOption设置(万一它们重要!)
  • 通过windows环境变量ING_SET = "SET LOCKMODE SESSION WHERE LEVEL = MVCC"设置锁模式。但我的测试表明,我们在SSIS中使用的ADO.NET驱动程序并没有对此进行验证(顺便说一句,我们为Squirrel或Tibco使用的JDBC驱动程序也没有做到这一点)。我相信这可能是ODBC特性。
  • 在数据流中的ADO.NET源步骤中发出命令。同样的语法错误。
  • UPDATE还尝试将SET ...命令包装在Ingres过程中,但这会导致语法错误,表明SET ...命令在过程中的任何地方都无效。

请任何人就如何从SSIS登记MVCC会话提供建议吗?

在这个阶段(我相信),我们被限制在ADO.NET驱动程序上,但是如果没有其他选项可以使用ODBC,那么就随它去吧。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-06 05:37:43

在这里回答我自己的问题。

设想了两种可能的办法。

1.使用脚本组件(在数据流步骤内)

在脚本组件中,我能够通过SET ...直接发出ADO.NET命令。

这种方法的问题在于,对于后续的(或并行的,在同一数据流中) ADO.NET源组件,我无法保留运行这些命令的连接。

试图通过事务通过特定的连接工作是不好的,因为这些命令必须在正在进行的事务之外发出。

因此,最终我还必须在这个组件中发出源select,即使这样也不太理想,因为随后的目标插入操作就不能与源选择在同一个事务中登记。

使用这种方法的解决方案是:-使用MVCC,将数据从源视图复制到源系统上的临时暂存表中。-然后使用事务,从源暂存表读取到目标系统。

代码如下(NB必须显式地添加对Ingres .NET Data Provider\v2.1\Ingres.Client.dll的引用

代码语言:javascript
复制
/* Microsoft SQL Server Integration Services Script Component
*  Write scripts using Microsoft Visual C# 2008.
*  ScriptMain is the entry point class of the script.*/

using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using Ingres.Client;
using System.Collections.Generic;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    private bool debug = true;

    private IDTSConnectionManager100 cm;
    private IngresConnection conn;


    public override void AcquireConnections(object Transaction)
    {
        // The connection manager used here must be configured in the Script Component editor's "Connection Managers" page.
        // "Connection" is the (default) strongly typed name for the first connection added.
        // In this case, it needs to be a reference to the xxxxx connection manager (by convention it should be "xxxxx_ADONET").
        cm = this.Connections.Connection;
        conn = (IngresConnection)cm.AcquireConnection(Transaction);
    }

    public override void PreExecute()
    {
        debugMessage("PreExecute", "Started");
        base.PreExecute();

        string viewName = Variables.vViewName;

        IngresCommand cmdSetSessionLockMode         = conn.CreateCommand();
        IngresCommand cmdSetSessionIsolationLevel   = conn.CreateCommand();
        IngresCommand cmdReaderQuery                = conn.CreateCommand();

        List<string> sqlCommandStrings = new List<string>();
        if (Variables.vUseIngresMVCC)
        {
            sqlCommandStrings.Add("SET LOCKMODE SESSION WHERE LEVEL = MVCC");
        }
        sqlCommandStrings.Add("SET SESSION ISOLATION LEVEL READ COMMITTED");
        sqlCommandStrings.Add(String.Format("MODIFY {0}_STAGING TO TRUNCATED", viewName));
        sqlCommandStrings.Add(String.Format("INSERT INTO {0}_STAGING SELECT * FROM {0}", viewName));

        foreach (string sqlCommandString in sqlCommandStrings)
        {
            debugMessage("PreExecute", "Executing: '{0}'", sqlCommandString);

            IngresCommand command = conn.CreateCommand();
            command.CommandText = sqlCommandString;
            int rowsAffected = command.ExecuteNonQuery();

            string rowsAffectedString = rowsAffected >= 0 ? rowsAffected.ToString() : "No";
            debugMessage("PreExecute", "Command executed OK, {0} rows affected.", rowsAffectedString);
        }

        debugMessage("PreExecute", "Finished");
    }

    public override void CreateNewOutputRows()
    {
        // SSIS requires that we output at least one row from this source script.
        Output0Buffer.AddRow();
        Output0Buffer.CompletedOK = true;
    }

    public override void PostExecute()
    {
        base.PostExecute();

        // NB While it is "best practice" to release the connection here,  doing so with an Ingres connection will cause a COM exception.
        // This exception kills the SSIS BIDS designer such that you'll be unable to edit this code through that tool.
        // Re-enable the following line at your own peril.
        //cm.ReleaseConnection(conn);
    }

    private void debugMessage(string method, string messageFormat, params object[] messageArgs)
    {
        if (this.debug)
        {
            string message = string.Format(messageFormat, messageArgs);
            string description = string.Format("{0}: {1}", method, message);
            bool fireAgain = true;
            this.ComponentMetaData.FireInformation(0, this.ComponentMetaData.Name, description, "", 0, ref fireAgain);
        }
    }
}
票数 0
EN

Stack Overflow用户

发布于 2015-08-06 05:39:45

在这里回答我自己的问题。

设想了两种可能的办法。

2.在现有数据库上设置一个启用MVCC的专用Ingres DBMS进程,并通过此进行连接。

这是我们目前正在追求的方法(因为它被支持,并且理想的透明)。我会更新的细节,一旦他们知道。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31644536

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档