SSIS 脚本任务引发死锁错误

Posted

技术标签:

【中文标题】SSIS 脚本任务引发死锁错误【英文标题】:SSIS Script Task is throwing deadlock error 【发布时间】:2022-01-08 05:29:36 【问题描述】:

我正在尝试查询数据库并发送电子邮件正文中的内容。对于我的用例,我尝试关注here。但是当我尝试运行包时,它会抛出死锁错误。谁能建议我错过了什么

脚本如下

namespace ST_ac39a1a4cb6047819cc46d683db46ac6

    [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    

        enum ScriptResults
        
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        

        public void Main()
        
            Variables varCollection = null;

            string User_Recepient_Email_ID = Dts.Variables["User::UserEml"].Value.ToString();

            Dts.VariableDispenser.LockForWrite("User::EmailData");
            Dts.VariableDispenser.GetVariables(ref varCollection);
            var data = varCollection["User::EmailData"].Value;

            OleDbDataAdapter da = new OleDbDataAdapter();
            DataTable dt = new DataTable();
            da.Fill(dt, varCollection["User::EmailData"].Value);

            SendMailMessage("loadJob@xyz.com", User_Recepient_Email_ID, "ETL Load Status Report", ConvertDataTableTohtml(dt), true, "smtp.xxxxxxxx.org");

            Dts.TaskResult = (int)ScriptResults.Success;
        


        public static string ConvertDataTableToHTML(DataTable dt)
        
            string html = "<table border ='1'>";
            //add header row
            html += "<tr>";
            for (int i = 0; i < dt.Columns.Count; i++)
                html += "<th>" + dt.Columns[i].ColumnName + "</th>";
            html += "</tr>";
            //add rows
            for (int i = 0; i < dt.Rows.Count; i++)
            
                html += "<tr style='color:blue;'>";
                for (int j = 0; j < dt.Columns.Count; j++)
                    html += "<td>" + dt.Rows[i][j].ToString() + "</td>";
                html += "</tr>";
            
            html += "</table>";
            return html;
        
        private void SendMailMessage(string From, string SendTo, string Subject, string Body, bool IsBodyHtml, string Server)
        
            MailMessage htmlMessage;
            SmtpClient mySmtpClient;

            htmlMessage = new MailMessage(From, SendTo, Subject, Body);
            htmlMessage.IsBodyHtml = IsBodyHtml;

            mySmtpClient = new SmtpClient(Server);
            mySmtpClient.Credentials = CredentialCache.DefaultNetworkCredentials;
            mySmtpClient.Send(htmlMessage);
           
    

还有任务脚本属性

运行包时出现错误

错误:脚本任务中的 0xC001405C:尝试锁定变量“User::EmailData”以进行读/写访问时检测到死锁。尝试 16 次后无法获取锁。锁超时。`

错误:脚本任务中的 0xC001405D:尝试锁定变量“System::InteractiveMode”以进行读访问和变量“User::EmailData”进行读/写访问时检测到死锁。尝试 16 次后无法获取锁。锁超时。

错误:脚本任务中的 0x1:尝试锁定变量“User::EmailData”以进行读/写访问时检测到死锁。尝试 16 次后无法获取锁。锁超时。 任务失败:脚本任务

警告:每个用户在 Foreach 循环中出现 0x80019002:SSIS 警告代码 DTS_W_MAXIMUMERRORCOUNTREACHED。 Execution 方法成功,但引发的错误数 (5) 达到了允许的最大值 (1);导致失败。当错误数量达到 MaximumErrorCount 中指定的数量时,就会发生这种情况。更改 MaximumErrorCount 或修复错误。 警告:SurplusMouse_EmailOrderDetail 处的 0x80019002:SSIS 警告代码 DTS_W_MAXIMUMERRORCOUNTREACHED。 Execution 方法成功,但引发的错误数 (5) 达到了允许的最大值 (1);导致失败。当错误数量达到 MaximumErrorCount 中指定的数量时,就会发生这种情况。更改 MaximumErrorCount 或修复错误。 SSIS 包

编辑

下面是查询

SELECT cus.CustomerNumber as CustomerNumber,cus.Location as ReceivingLocation, 
       i.StrainName as StrainName,i.StrainCode as StrainCode,i.Age as Age,
       i.Sex as Sex,i.Genotype as Genotype,i.RoomNumber as SentFrom,io.OrderQuantity as OrderQuantity
FROM [dbo].[MouseOrder] mo
JOIN [dbo].[Customer] cus on cus.Customer_ID = mo.CustomerId
JOIN [dbo].[InventoryOrder] io on io.OrderId = mo.MouseOrder_ID
JOIN [dbo].[Inventory] i on i.Inventory_ID =  io.InventoryId 
WHERE mo.OrderDate = convert(date,getdate() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time') and mo.SAMAccountEmail = ?

【问题讨论】:

你的底层数据库是SQL Server吗? 是的,它是 Azure SQL 数据库 【参考方案1】:

有更好的方法。

步骤:

    创建将生成 (X)HTML 正文的 SQL Server 存储过程 通过 XML/XQuery 发送电子邮件。 通过 SSIS Execute SQL 任务调用该 sp,并将其输出分配给 SSIS 变量。 调用 SSIS 脚本任务从步骤 #2 中传递一个包含 (X)HTML 电子邮件正文的变量以发送电子邮件。

好处:

没有字符串连接。 不用担心 NULL 值。 非常容易创建,非常容易维护。 UI 样式通过 CSS 控制。

这是一个概念性的例子。

SQL

DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, [Name] VARCHAR(20), Number CHAR(5), [Address] VARCHAR(100));
INSERT INTO @tbl (Name, Number, Address) VALUES
('Bob  ', '12345' ,'1 Street, Town'),
('John ', '23456' , NULL),
('Scott', '34567' ,'3 Avenue, City');

DECLARE @xhtmlBody XML
   , @body NVARCHAR(MAX)
   , @tableCaption VARCHAR(30) = 'Customers list';

SET @xhtmlBody = (SELECT (
SELECT * FROM @tbl 
FOR XML PATH('row'), TYPE, ROOT('root'))
.query('<html><head>
            <meta charset="utf-8"/>
            (: including embedded CSS styling :)
            <style>
            table <![CDATA[ border-collapse: collapse;  width: 300px; ]]>
            th <![CDATA[ background-color: #4CAF50; color: white; ]]>
            th, td <![CDATA[  text-align: left; padding: 8px; ]]>
            tr:nth-child(even) <![CDATA[ background-color: #f2f2f2; ]]>
            #green <![CDATA[ background-color: lightgreen; ]]>
         </style>
         </head>
         <body>
<table border="1">
   <caption><h2>sql:variable("@tableCaption")</h2></caption>
   <thead>
      <tr>
        <th>No.</th>
        <th>Name</th>
        <th>Number</th>
        <th>Address</th>
      </tr>
   </thead>
   <tbody>

    for $row in /root/row
    return <tr>
            <td>data($row/ID)</td>
            <td>data($row/Name)</td>
            <td>data($row/Number)</td>
            <td>data($row/Address)</td>
        </tr>

</tbody></table></body></html>'));

SELECT @xhtmlBody;

SET @body = CAST(@xhtmlBody AS NVARCHAR(MAX));

【讨论】:

谢谢!!我对 SSIS 和 SP 很陌生。我采取的方法没有什么可以解决的 只需将建议的解决方案复制到 SSMS,按原样运行,然后查看它的作用。 查询生成具有带参数过滤器的电子邮件正文。SP 可以接受参数吗? 当然,是的。 我添加了具有连接和过滤参数的 Sql 查询,您可以看看,如果我可以通过 SP 做到这一点,请告诉我【参考方案2】:

使用你得到的东西,错误是从你与变量交互的方式中蔓延出来的。您提供的代码是他在 2005 时代必须做的事情,尽管当时它应该是 VB.NET,因为 C# 不是一个选项。您应该能够通过 Dts.Variables 集合直接访问变量,然后获取它们的 Value - 转换为字符串或根据需要保留为对象类型。

        string User_Recepient_Email_ID = Dts.Variables["User::UserEml"].Value.ToString();
        var data = Dts.Variables["User::EmailData"].Value;

        OleDbDataAdapter da = new OleDbDataAdapter();
        DataTable dt = new DataTable();
        da.Fill(dt, data);

看起来您实际上并未写入这些值,因此我将在第一个屏幕截图中将它们从 ReadWrite 更改为 ReadOnly。

【讨论】:

非常感谢它确实帮助解决了错误。但我没有在我的电子邮件中看到数据。我发布了一个不同的问题***.com/questions/70193123/… 你能帮我建议我错过了什么

以上是关于SSIS 脚本任务引发死锁错误的主要内容,如果未能解决你的问题,请参考以下文章

SSIS 脚本任务抛出未设置为对象实例的对象引用

部署时SSIS任务脚本损坏

SSIS 数据流脚本任务错误处理

调用目标引发的运行时错误豁免

无法使用脚本任务从 SSIS 发送邮件 - 超时

在 SSIS 包中将参数值传递给变量会导致运行时错误