【问题标题】:SQLCLR execution fails within a trigger: "transaction context in use by another session."SQLCLR 执行在触发器内失败:“另一个会话正在使用事务上下文”。
【发布时间】:2018-01-10 16:46:45
【问题描述】:

我尝试执行一个使用HttpWebRequest 的SQLCLR 存储过程。如果我单独执行,一切运行良好:

DECLARE @idReservation uniqueidentifier
DECLARE @motif int
DECLARE @idCuma uniqueidentifier

set @idReservation = '52D1A203-A102-464A-8E2D-652B02A2ABDB'

set @idCuma = '40EAB86E-A61B-4646-8AFB-F2C77264E337'

-- À faire : définir des valeurs de paramètres ici.

EXECUTE [BDchantiers].[dbo].[CLRenvoyerUnSms] 
   @idReservation 
  ,1
  ,@idCuma
GO

但是当我尝试在我的触发器中使用它时,我的触发器甚至无法运行:

USE [BDchantiers]
GO
/****** Trigger [dbo].[tr_HAB_Chantier_delete]    Script Date: 08/03/2017 09:39:06 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER trigger [dbo].[tr_HAB_Chantier_delete] on [dbo].[Chantier]
after delete
not for replication
as
declare @chaID uniqueidentifier
declare @rolID uniqueidentifier
declare @cumaID uniqueidentifier
declare @oldRespID uniqueidentifier

-- ID du role 'opérateur de chantier'
set @rolID = 'FA236022-B6EB-4A25-8711-59693747CDDF'
select @cumaID = ACT_ENT_CLEF from deleted i join activite a on i.CHA_ACT_CLEF = a.ACT_CLEF
select @chaID = CHA_ID from deleted
EXECUTE [BDchantiers].[dbo].[CLRenvoyerUnSms] 
    '52D1A203-A102-464A-8E2D-652B02A2ABDB',
    1,
    '40EAB86E-A61B-4646-8AFB-F2C77264E337'
select @oldRespID = CHA_UTL_CLEF from deleted
...

我收到以下错误:

另一个会话正在使用事务上下文。

此代码执行 http 请求:

 public static void SendRequest(string postData)
    {
        string address = "http://www.envoyer**.com/api/message/send";
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
        request.ContentType = "application/x-www-form-urlencoded";
        request.Method = "POST";
        string portiklogin = "****";
        string portikpassword = "****";
        NetworkCredential myCred = new NetworkCredential(portiklogin, portikpassword, "");
        request.Credentials = myCred;    

        using (var streamWriter = new StreamWriter(request.GetRequestStream()))
        {
            //string json = byteArray;

            streamWriter.Write(postData);
            streamWriter.Flush();
        }

除此之外,还需要做很多数据库连接(拥有触发器/DBchantiers 的同一数据库)。

我只是这样创建连接:

 public static void envoyerUnSms(SqlGuid idReservation, int motif, SqlGuid idCuma)
{
    using (SqlConnection conn = new SqlConnection())
    {

        conn.ConnectionString = "Data Source=*****; Initial Catalog=BDchantiers;Integrated Security=False;  User Id=***; Password=****; MultipleActiveResultSets=True";

        conn.Open();
        int sold = CalculerSoldeSMS(idReservation, motif, idCuma, conn);

        GererEnvoiSMSReservation(idReservation, motif, sold, conn);

    }

感谢您的回答!

【问题讨论】:

  • HttpWebRequest 本身不是问题,至少对于事务上下文而言不是问题。您需要发布一些 .NET 代码,以便我们可以看到发生了什么,以及为什么它甚至会查看事务上下文。另外,请注意,在触发器中调用 URI 本质上是危险的,尤其是在您没有更改默认 URI 连接限制(大多数人不知道)的情况下。
  • 作为@SolomonRutzky syas,请展示一些CLR代码。我的假设是,除了 HttpWebRequest 之外,您还在 CLR 代码中进行某种数据库访问,这就是导致异常的原因。

标签: sql-server tsql transactions sqlclr database-trigger


【解决方案1】:

我终于找到了解决办法!

正如@SolomonRutzky 所说,我正在我的 CLR 代码中进行数据库连接,为此,我使用了创建新上下文的经典连接字符串。当我改变我的连接时,我解决了这个问题:

“上下文连接=true”

根据另一个带有此连接字符串的帖子 (The difference between the connections strings in SQLCLR),上下文连接使用用户已经建立的与服务器的连接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    • 1970-01-01
    • 2019-01-16
    • 1970-01-01
    • 2020-09-30
    • 2011-03-10
    • 1970-01-01
    相关资源
    最近更新 更多