TSQL: Trigger on Commit

耗尽温柔 提交于 2019-12-23 12:12:07

问题


We have a back office system that inserts invoice information into an SQL database via a MSDTC stored procedure, the application inserts header, then the detail information.

I have set up a CLR trigger on the header table that fires when a record is inserted.

The problem I am having is that the trigger is firing before the COMMIT TRANSACTION meaning that the details information might not be populated, which is required by the process that is triggered. Also if the system fires a ROLLBACK TRANSACTION the trigger has already fired.

I understand that triggers can't be assigned to a COMMIT, but was wondering if any one had any other thoughts.

I stumbled across a suggested solution for oracle where you create a Materlised View that updates ON COMMIT, and tried to find the TSQL equivalent which is Indexed Views, but had no luck implementing it.

To Summarise:
Is it possible to trigger upon a COMMIT TRANSACTION possibly using Indexed Views ?


CLR Trigger Code

Sends a JMS Message to a queue, to be processed by 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;
    }

}

回答1:


After helpful comments stating that utilizing the commit in a trigger wasn't possible.

I reviewed the ESB process that was kicked off by trigger, the process now queries the data with the passed information, this has fixed my problem due to the fact that the BEGIN TRANSACTION creates a lock on the data the query doesn't return results until there has been COMMIT TRANSACTION, thus meaning the process won't continue until the query returns data, so the Invoice details will always be populated.

Also if there was a ROLLBACK TRANSACTION, the process would time out throwing an error as expected.




回答2:


See this article, you'll probably have to use context_info and then fire the trigger afterwards for those records...

Is there a way to disable a SQL Server trigger for just a particular scope of execution?



来源:https://stackoverflow.com/questions/13860816/tsql-trigger-on-commit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!