2

我想知道是否有内存数据库实现,可以跨多个 AppDomain 使用相同的内存数据库实例。

动机。像那里的许多人一样,我们对我们的客户端-服务器应用程序进行了集成测试。有几种测试模式,从最重的一种——现实生活场景,客户端、服务器和数据库都位于不同的机器上,到最轻量的一种,客户端和服务器只是同一个进程中的两个 AppDomain并且数据库是同一台机器上的 sqlite 文件。

自然,轻量级场景是最快的,开发人员经常使用它,而重度场景在每次构建时在我们的 CI 服务器上运行。

我的目标是通过使用内存数据库进一步加速轻量级场景。

问题。好的,所以 sqlite 有一个内存数据库选项,但是这样一个数据库:

  • 在与它的连接关闭后被处理掉。
  • 不能有两个打开的连接,新连接打开另一个数据库实例。

不幸的是,我需要两个 - 一个用于测试暂存代码,它在客户端 AppDomain 中运行,另一个用于服务器端 DAL。

我意识到 sqlite 内存数据库工作方式背后的基本原理。我也意识到在两个 AppDomain 之间共享内存数据库的困难。如何在两个 AppDomain 之间共享内存缓冲区而不恢复到内存映射文件(而且我不想处理任何文件系统 API)?

我看到的唯一有效的解决方案是让两个 AppDomain 共享一个非托管内存缓冲区,其中缓冲区的句柄将从一个 AppDomain 传递到另一个。但是是否有任何支持此设置的内存数据库实现?

(一种低效的解决方案是将整个数据库从一个 AppDomain 传递到另一个 AppDomain,然后再返回)。

我的分析可能完全错误,我可能会错过一些简单的解决方案。无论如何,我想知道是否有人遇到过同样的问题以及他们是如何解决的。

附言

我真的很想避免使用任何类型的文件 API,比如内存映射文件。

4

2 回答 2

1

我想到了三个解决方案,但它们都需要一些配置。它们都要求您创建第三个 AppDomain,其中内存数据库作为单例驻留,并编写一个具有该数据库定义明确接口的类。

第一个解决方案是跨 AppDomain 调用代码。您传递的对象必须是“可远程处理的”,这可能是个大问题。(派生自 MarshalByRefObject 等)不仅如此,您传入或传出 AppDomain 的任何对象都必须是可序列化的。它是可行的,但有时它并不漂亮。

第二种解决方案是使用远程处理。它现在是旧技术,但它仍然有效。它基本上形式化了上述跨 AppDomains 的调用。在这里我就不多说了,提起这件事我都快尴尬了。

第三种解决方案是使用 WCF 和快速的 namedPipeBinding。WCF 调用的两端可以在同一个应用程序中,也可以在不同的应用程序域中。以这种方式编码的一个副作用是,您可以稍后将内存数据库切换为功能齐全的数据库,并将绑定更改为通过 Intranet 或 Internet 工作。

第三种解决方案是我目前用于类似于您所描述的项目的解决方案。我们的目标是隔离数据库,这样我们就可以在不“污染”其余层的情况下试用 nHibernate。

于 2009-09-03T07:18:03.243 回答
0

我不知道任何这样的数据库。

但是想想这样的数据库可以有什么形式是很有趣的。如果我们将应用程序域视为轻量级进程,那么我们可以将跨域对话(序列化)视为消息传递。然后我们可以定义一个简单的消息协议,允许客户端发送查询,并作为响应获得结果。

  1. 您的数据库应在其自己的应用程序域中运行
  2. 每个客户端都应该在自己的应用程序域中运行
  3. 应用程序域之间的标准序列化应该用于返回查询结果。最简单的方法是将查询封装在它们自己的类中,这些类在构造时执行。这样,您可以使用AppDomain.CreateInstance
  4. 您的数据库应该能够处理来自任何线程的请求。

我不认为这是一个好主意。应用程序域如何工作和互操作的细节太多,无法做到 100% 正确。

于 2009-09-03T07:15:08.277 回答