CLR触发状态

| 我考虑使用CLR触发器代替传统的T-SQL,因为我需要使用已经在C#中实现的某些逻辑。我知道SQL Server支持CLR集成,就我而言,这似乎是一个值得一试的解决方案。 但是,我要执行的操作可能会有点慢。不能完全排除在触发的操作中完全使用它们的速度,但是在插入成千上万条记录时可能会明显慢。最慢的部分可以从缓存中受益匪浅,我想这将是很少的缓存未命中和成千上万的缓存命中。在这一点上,这一切都引发了一个问题:CLR触发器可以具有任何状态吗?而且,更重要的是,这种状态的生命周期是什么? 我想我可以使用触发器类的静态字段来保存一些状态,但是我不知道它何时初始化(服务器启动时?事务启动时?未指定?)。我不确定这是否安全,因此请问在CLR触发器中使用某些状态的常用做法是(如果有)。 为避免混淆:我需要缓存CLR对象,而不是某些SQL查询的结果,因此,这与SQL Server本身在缓存方面的表现无关,我想缓存一些不属于数据库的数据。另外,我认为CLR并不是因为我无法在T-SQL中进行字符串操作和绑定检查。我需要执行一些CLR类库中实现的逻辑,该逻辑具有很多依赖性。在这种情况下,我是否应该使用触发器是另一个与此问题几乎无关的问题。 提前谢谢了。 PS:我将不胜感激您对主题的任何评论和见解,即使是那些不能直接回答我的问题的评论和见解,也请不要完全理解“触发器是邪恶的,永远不应该使用”和“ CLR集成速度慢,并且兼容性很困难”。另外,我知道它可能会向某人大喊“过早的优化”,但是由于我是SQL Server中的CLR集成的新手,所以我现在只想知道我的优化选项正在使用。除非分析结果表明如此,否则我不会对其进行优化,但是我不想实施整个过程以意识到它太慢了,我对此无能为力。 我使用SQL Server 2008和.NET 3.5。     
已邀请:
尽管可以在SQLCLR触发器类中使用“ 0”类字段来缓存值,但是您需要特别注意以下几点: 您打算缓存多少数据?您不想占用过多的内存,而应将SQL Server用于查询。 每个程序集所有者的每个数据库只有一个AppDomain(即程序集上的“ 1”)。这意味着任何特定程序集中的代码都在所有SQL Server会话(即SPID)之间共享。如果数据只是查找数据,并且不会根据哪个进程与静态字段进行交互而更改,那么就可以了。但是,如果每个进程的数据不同,那么除非您将诸如当前TransactionID之类的值与进程相关联,否则这将产生“奇数”行为。 如果数据是每个进程的数据,则假定您找到一种区分每个特定SPID / SESSION的方法,那么您将如何清理旧数据?它会一直存在于内存中,直到明确删除或卸载AppDomain。对于要与所有人共享的通用查找数据来说,这不是问题,因为这种类型的数据不会随着每个新流程而增加。但是,除非清除,否则每个进程的数据将持续增加。 可以出于各种原因(内存压力,Assembly的删除/重新创建,与Assembly有关的安全性更改,与DB有关的安全性更改,运行
DBCC FREESYSTEMCACHE(\'ALL\')
等)随时卸载AppDomain。如果一个进程依赖于先前进程缓存的数据,如果正在缓存的数据可能导致顺序进程之间出现不同的结果,则不能保证这可以正常工作。如果在进程之间丢弃高速缓存仅导致需要重新加载高速缓存,那么应该没问题。 其他说明(但没有什么要谨慎的): 当在程序集中调用第一个方法时(其中该程序集所在的数据库当前没有运行AppDomain且该程序集的授权者用户),将加载AppDomains。 由于上述原因之一,AppDomain将一直保持加载状态,直到被SQL Server卸载为止,但是这些情况均不会发生。这意味着AppDomain可以保持很长的加载时间(即直到服务器/服务重新启动)。 第一次引用每个程序集内部的方法时,将加载每个程序集。 为了利用loading事件,您可以将代码放在静态类构造中。请注意,没有可用的``3'',因此您不能在使用进程内上下文连接的静态类构造函数中创建任何``4''(即``5'')。     

要回复问题请先登录注册