开发者社区> 问答> 正文

SQL Server-尝试完成事务时注册要运行的用户代码

我有一个SQL CLR存储过程,该存储过程注册了一个事件处理程序以完成当前事务

[SqlProcedure]
public static void MySProc()
{
    Transaction.Current.TransactionCompleted += new TransactionCompletedEventHandler(Current_TransactionCompleted);

    Transaction.Current.Rollback(); //###Current_TransactionCompleted called here###
}

static void Current_TransactionCompleted(object sender, TransactionEventArgs e)
{
}

这是T-SQL调用代码

begin tran
EXEC    [dbo].[MySProc]
commit tran

这按预期工作:在调用“ Transaction.Current.Rollback()”后,处理程序被执行。

但是,我感兴趣的是在“ MySProc()”以外完成事务时调用我的处理程序(或我的代码)。

[SqlProcedure]
public static void MySProc()
{
    Transaction.Current.TransactionCompleted += new TransactionCompletedEventHandler(Current_TransactionCompleted);
}

static void Current_TransactionCompleted(object sender, TransactionEventArgs e)
{
}
begin tran
EXEC    [dbo].[MySProc]
rollback tran -- ###Current_TransactionCompleted NOT called###

这可能吗? 如果没有,还有其他方法可以挂钩当前事务完成并在事务结果(提交或回滚)上带有“最后的字眼”吗

展开
收起
祖安文状元 2020-01-05 14:50:04 382 0
1 条回答
写回答
取消 提交回答
  • 起初我以为根本不可能,但是经过进一步的调查,我发现这是一定程度的。在我的第一个测试中,我正在通过SqlContext.Pipe.Send("...");调用处理程序时打印出一条消息。它从不显示任何内容,因此我认为没有被调用。但是,我忘记SqlContext了事件处理程序中没有活动对象,因为它与调用过程(即启动它的会话)断开了连接。一旦我切换到File.WriteAllText()在事件处理程序中使用,那么我可以看到确实在执行任何SQLCLR代码COMMIT或ROLLBACK在其之外调用了它。而且,我用的是Transaction.Current.TransactionCompleted一样的问题,而不是使用静态变量,就像我最初使用的那样。并且,由于我们引用的是“当前”事务(即它已经在上下文连接中被征募),因此无需征募任何东西。

    但是,我应该澄清,在事务已提交或回滚之后,有效的“ this”只是使一些SQLCLR代码得到执行。我什至通过在开始事务和注册处理程序之后终止会话来进行测试,它确实触发了事件处理程序。

    但是,大多数问题的措词与该问题标题的措词(加了强调)之间略有脱节- 尝试在交易完成时注册要运行的用户代码-因为它们似乎指示完成交易的不同时间处理程序应在何时运行。

    如果没有,还有其他方法可以挂钩当前事务完成并在事务结果(提交或回滚)上带有“最后的字眼”吗?

    我会说:不仅“不”(至少不是我所知道的),而且您也不希望它是“是”,因为交易可能由于各种原因而被杀死(死锁,会话被杀死,连接池执行sp_reset_connection,批处理级别错误,任何错误(如果XACT_ABORT是ON,等等),您确实不想干扰SQL Server管理事务的能力。

    据我所知,最接近的是为“提交”和“回滚”创建SQLCLR方法(类似于问题中的示例代码),并要求您的使用仅使用那些SQLCLR存储过程来执行这些操作。

    在SQLCLR事件处理程序运行后的COMMIT或ROLLBACK。这不是事件处理程序,它不是由结束事务的请求触发的,而是由实际完成的事务触发的。在这一点上,没有办法“说了最后一句话”。

    2020-01-05 14:50:11
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
SQL Server 2017 立即下载
GeoMesa on Spark SQL 立即下载
原生SQL on Hadoop引擎- Apache HAWQ 2.x最新技术解密malili 立即下载