`DataTypeFactory::get` locks a mutex inside shared a context, there was a case when many threads were locked inside it

https://pastila.nl/?0043b3e6/c557368f4cf0eb87a3c6f2cc162bc693

It is not clear which thread locked the mutex for a long time. However, it may be possible to lock less inside `DataTypeFactory::get`.
class Session;
struct WriteSettings;
class IInputFormat;
class IOutputFormat;
using InputFormatPtr = std::shared_ptr<IInputFormat>;
using OutputFormatPtr = std::shared_ptr<IOutputFormat>;
class IVolume;
using VolumePtr = std::shared_ptr<IVolume>;
struct NamedSession;
struct BackgroundTaskSchedulingSettings;
#if USE_NLP
    class SynonymsExtensions;
    class Lemmatizers;
#endif
class Throttler;
using ThrottlerPtr = std::shared_ptr<Throttler>;
class ZooKeeperMetadataTransaction;
using ZooKeeperMetadataTransactionPtr = std::shared_ptr<ZooKeeperMetadataTransaction>;
class AsynchronousInsertQueue;
using ExternalTablesInitializer = std::function<void(ContextPtr)>;
using InputInitializer = std::function<void(ContextPtr, const StoragePtr &)>;
using InputBlocksReader = std::function<Block(ContextPtr)>;
using ReadTaskCallback = std::function<String()>;
using MergeTreeReadTaskCallback = std::function<std::optional<PartitionReadResponse>(PartitionReadRequest)>;
#if USE_ROCKSDB
class MergeTreeMetadataCache;