运行powershell命令行开关时:
Set-AzureRmSqlDatabaseTransparentDataEncryption
在并行和单独的运行空间中,我们看到了下面的堆栈跟踪的瞬态/间歇性故障。但是,当我们连续运行同一个命令行开关时,我还没有看到这个问题发生。
到目前为止,我提出了可能的原因:
{ReleaseUser}\AppData\Roaming\Windows Azure Powershell\ErrorRecords\Set-AzureRmSqlDatabaseTransparentDataEncryption_YYYY-MM-DD-THH-MM-SS-PPP.log
上的争用/锁定,其中命令行开关似乎记录了与解析令牌相关的信息(此文件中没有实际错误)。运行此命令的其中一个脚本的堆栈跟踪:
[例外:System.NullReferenceException:对象引用未设置为对象的实例。\ r \ n \
at System.Collections.Specialized.OrderedDictionary.OrderedDictionaryEnumerator.get_Value()\ r \ n
在Microsoft.Azure.Commands.Common.Authentication.Factories.ClientFactory.GetCustomHandlers()\ r \ n \ n 在Microsoft.Azure.Commands.Common.Authentication.Factories.ClientFactory.CreateClient [TClient](AzureContext context,Endpoint endpoint)\ r \ n
在Microsoft.Azure.Commands.Sql.TransparentDataEncryption.Services.AzureSqlDatabaseTransparentDataEncryptionCommunicator.GetCurrentSqlClient(String clientRequestId)\ r \ n
在Microsoft.Azure.Commands.Sql.TransparentDataEncryption.Adapter.AzureSqlDatabaseTransparentDataEncryptionAdapter.GetTransparentDataEncryption(String resourceGroupName,String serverName,String databaseName)\ r \ n
在Microsoft.Azure.Commands.Sql.TransparentDataEncryption.Cmdlet.SetAzureSqlDatabaseTransparentDataEncryption.GetEntity()\ r \ n
在Microsoft.Azure.Commands.Sql.Common.AzureSqlCmdletBase' 2.ExecuteCmdlet()\ r \ n
在Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet.ProcessRecord()] \
堆栈跟踪对于运行相同命令行开关的第二个线程:
消息:"对象引用未设置为对象的实例。",来源:"系统",StackTrace:" at System.Collections.Specialized.OrderedDictionary.IndexOfKey(Object key)\ r \ n at System.Collections.Specialized.OrderedDictionary.set_Item(Object key,Object value)\ r \ n在Microsoft.Azure.Commands.Common.Authentication。 Factors.ClientFactory.AddHandler [T](T处理程序)\ r \ n在Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet.BeginProcessing()\ r \ n在System.Management.Automation.Cmdlet.DoBeginProcessing()\ r \ n \ n在System.Management.Automation.CommandProcessorBase.DoBegin()"`
可疑:根据堆栈跟踪枚举/访问System.Collections.Specialized.OrderedDictionary
时,这两个命令都会爆炸。
重要性:该命令的两个实例是否正在访问 SAME 字典?
答案 0 :(得分:3)
Will的回答似乎支持我们怀疑这个(和其他)命令行程序不是线程安全的。为了解决这个问题,我们使用互斥锁作为协调机制“锁定”调用这些命令行开关。
使用此线程作为灵感,在powershell中构建了一个过程锁定/协调机制(使用互斥锁)的简单实现:
function thisFunctionIsCalledFromTheHtml() {
// Get the JSON data by using a XML http request
var listData;
var xhr = new XMLHttpRequest();
// The request needs to be synchronous for now because on slow connections the DOM is ready
// before it fetches everything from the json file
xhr.open('GET', 'records.json', false);
xhr.addEventListener("load", function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
listData = JSON.parse(xhr.responseText);
} else {
console.error('Error: ' + xhr.status + ' ' + xhr.statusText);
}
}
});
xhr.addEventListener("error", function() {
console.error('Error: ' + xhr.status + ' ' + xhr.statusText);
});
xhr.send(null);
document.addEventListener("DOMContentLoaded", function() {
var placeholderKeys = [];
for (var key in listData) {
var value = listData[key];
placeholderKeys = placeholderKeys.concat(value.title, value.abbr, value.keywords);
}
var filterInput = document.getElementById('input-id');
filterInput.placeholder = placeholderKeys[
Math.floor(Math.random() * placeholderKeys.length)
];
});
}
希望这有助于某人。
答案 1 :(得分:2)
@MSC,
是否知道此命令行开关不是线程安全的? (故意还是错误?)
<强>原因:强>
据我所知,它依赖于类库是否是线程安全的。从源代码(http://referencesource.microsoft.com/#System/compmod/system/collections/specialized/ordereddictionary.cs,d02ab0d292f01b57),我们可以看到函数(IndexOfKey(key)
)。它与objectsArray
更相关。我们可以看到这个目标代码如下:
private ArrayList objectsArray {
get {
if (_objectsArray == null) {
_objectsArray = new ArrayList(_initialCapacity);
}
return _objectsArray;
}
}
看来如果我们使用并行线程调用此函数,它将抛出异常。它没有被锁定。
<强> HOWTO:强>
使用锁定机制锁定powershell中的“objectArray
”
使用单线程调用此函数。
希望有所帮助。