SQLCLR在触发器中执行失败:“另一个会话正在使用的事务上下文。”

时间:2017-08-03 07:54:16

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

我尝试执行使用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);

    }

感谢您的回答!

1 个答案:

答案 0 :(得分:0)

我终于找到了解决方案!

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

“context connection = true”

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