Quero forçar o AppDomain que está sendo usado pelo SQLCLR a ser redefinido. Como posso fazer isso além de reiniciar a instância do SQL Server?
Quero forçar o AppDomain que está sendo usado pelo SQLCLR a ser redefinido. Como posso fazer isso além de reiniciar a instância do SQL Server?
Respostas:
Sei que isso é um pouco brutal, mas que tal desabilitar o CLR e reativá-lo?
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 0;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO
ALTER ASSEMBLY
propagado via envio de logs que não recarregou (ou pelo menos descarregou) o Domínio do Aplicativo foi o bug. De qualquer maneira, encontrei um método ainda mais fácil que adicionei à minha resposta aqui. Se você tivesse a capacidade de testar esse novo método, seria ótimo, pois estou muito curioso para ver se ele funciona no cenário de envio de logs que você descreveu.
Existe uma solução mais elegante que não afeta todos os outros assemblies: basta alterar o PERMISSION_SET de um dos assemblies no domínio do aplicativo (os domínios do aplicativo são por usuário).
ALTER ASSEMBLY [AssemblyName] WITH PERMISSION_SET = {1 of the 2 levels that
this assembly is not current at}
Lembre-se de que você precisará definir o PERMISSION_SET de volta ao que era. Além disso, você precisa acessar um método na montagem antes de alterar o PERMISSION_SET para descarregá-lo; alterar um assembly que não está atualmente carregado em um domínio de aplicativo ativo, mas com outro assembly, não afeta o domínio de aplicativo (os domínios de aplicativo são por DB, por usuário e não por assembly).
ATUALIZAÇÃO
O método descrito acima é a abordagem mais refinada em que apenas descarrega esse domínio de aplicativo. Porém, exige que a montagem possa ser configurada para um dos outros dois níveis. Para montagens marcadas como SAFE
somente será possível se
TRUSTWORTHY ON
ouEXTERNAL ACCESS ASSEMBLY
a UNSAFE ASSEMBLY
permissão ou a permissãoNesse caso, você pode simplesmente alterar a TRUSTWORTHY
configuração ON
e voltar imediatamente imediatamente OFF
e isso descarregará todos os domínios de aplicativo nesse banco de dados específico:
ALTER DATABASE CURRENT SET TRUSTWORTHY ON;
ALTER DATABASE CURRENT SET TRUSTWORTHY OFF;
Se você tiver apenas um domínio de aplicativo no banco de dados de qualquer maneira (e suspeito que esse seja o caso em 95% ou mais do tempo), os dois métodos descritos aqui têm o mesmo efeito líquido. E nessa situação, o ALTER DATABASE
método parece mais simples, pois não requer a especificação de um nome de objeto específico, nem o conhecimento do original PERMISSION_SET
.
Além disso, se você tiver apenas um único domínio de aplicativo, o ALTER DATABASE
método será mais simples, mesmo no caso em que o banco de dados já esteja definido TRUSTWORTHY ON
ou você tenha configurado o login da base de chave com a permissão apropriada. Se você estiver usando um logon baseado em chave, poderá definir TRUSTWORTHY
como ON
e OFF
novamente como mencionado acima. Mas se você já tiver TRUSTWORTHY
definido ON
, basta inverter e configurá-lo como OFF
e, em seguida, retornar imediatamente para ON
:
ALTER DATABASE CURRENT SET TRUSTWORTHY OFF;
ALTER DATABASE CURRENT SET TRUSTWORTHY ON;
SELECT * FROM sys.dm_clr_appdomains;
. Doce.