2012-12-13 57 views
4

我们有一个后台系统,通过MSDTC存储过程将发票信息插入SQL数据库,应用程序将插入标题,然后插入详细信息。TSQL:提交时触发

我在头表上设置了一个CLR触发器,它在插入记录时触发。

我遇到的问题是触发器在COMMIT TRANSACTION之前触发,这意味着可能未填充详细信息,这是触发的进程所需的。此外,如果系统触发了一个ROLLBACK TRANSACTION,触发器已经触发。

据我所知,触发器不能被分配到COMMIT,但想知道是否有任何其他的想法。

我偶然发现了一个针对oracle的建议解决方案,您在其中创建Materlised视图并更新ON COMMIT,并试图找到等价于Indexed Views的TSQL,但没有实现它的运气。

总结:
是否有可能在一个COMMIT TRANSACTION可能使用索引视图触发?


CLR触发器代码

发送一个JMS消息到队列,由Sonic ESB进行处理。

[Microsoft.SqlServer.Server.SqlTrigger(Name = "InvoiceTrigger", Target = "Table", Event = "FOR INSERT")] 
public static void InvoiceTrigger() 
{ 
    //Declare Connection vairables 
    string connectionURL, connectionDomain, connectionUser, connectionPassword, connectionQueue; 
    //Constant 
    connectionUser = "user"; 
    connectionPassword = "pass"; 
    connectionQueue = "Queue"; 
    //Local Environment 
    connectionURL = "tcp://IP:2506"; 
    connectionDomain = "Domain1"; 

    //Create connection sonic domain 
    SonicSend send = new SonicSend(connectionURL, connectionDomain, connectionUser, connectionPassword, connectionQueue); 

    //Send Test message to pipe 
    SqlCommand command; 
    SqlTriggerContext triggContext = SqlContext.TriggerContext; 
    SqlPipe pipe = SqlContext.Pipe; 
    SqlDataReader reader; 
    switch (triggContext.TriggerAction) 
    { 
     case TriggerAction.Insert: 
      // Retrieve the connection that the trigger is using 
      using (SqlConnection connection = new SqlConnection(@"context connection=true")) 
      { 
       connection.Open(); 
       command = new SqlCommand(@"SELECT LSH_LINKCODE, DOC_CODE, LSH_DOCNUM FROM INSERTED;", connection); 
       reader = command.ExecuteReader(); 
       if (reader.HasRows) 
       { 
        string xml; 
        char cr = (char)13; 
        int i = 0; 
        while (reader.Read()) 
        { 

         xml = @"<Invoice action='insert'>"; 
         xml += "<LinkCode>" + reader.GetString(0).ToString() + "</LinkCode>"; 
         xml += "<DocumentCode>" + reader.GetString(1).ToString() + "</DocumentCode>"; 
         xml += "<DocumentNumber>" + reader.GetString(2).ToString() + "</DocumentNumber>"; 
         xml += @"</Invoice>"; 
         i++; 
         send.testJMSsend(xml); 

        } 

       } 

       reader.Close(); 
      } 
      break; 
    } 

} 
+0

为什么不把触发器中的代码放在事务中呢? – twoleggedhorse

+2

简短的回答是,“否” – SQLMason

+0

在这种情况下,您需要重新考虑您的代码。在触发导致触发器的插入/更新之前,您需要获取所有信息(可能在保留表中)。你没有发布任何代码,所以很难提供帮助。回滚还将回滚事务期间触发器所做的任何更改。 – twoleggedhorse

回答

1

有益的意见指出,利用在提交后触发是不可能的。

我查看了由触发器启动的ESB进程,现在进程使用传递的信息查询数据,这已解决了我的问题,因为BEGIN TRANSACTION创建了对查询没有的数据的锁定返回结果直到COMMIT TRANSACTION,这意味着该过程将不会继续,直到查询返回数据,因此发票细节将始终填充。

此外,如果有ROLLBACK TRANSACTION,过程将超时如预期抛出错误。