AppDomain边界内可用的内存数据库

时间:2009-09-03 06:57:23

标签: .net in-memory-database

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

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

当然,轻量级场景是最快的,开发人员经常使用它,而重型场景则在每个版本的CI服务器上运行。

我的目标是通过使用内存数据库进一步加快轻量级方案。

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

  • 在与其连接关闭后被丢弃。
  • 不能有两个打开的连接,新连接打开另一个数据库实例。

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

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

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

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

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

P.S。

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

2 个答案:

答案 0 :(得分:1)

我想到了三个解决方案,但所有这些解决方案都需要一些配置。它们都要求您创建第三个AppDomain,其中内存数据库作为s单例存在,并为具有定义良好的数据库接口的类编写代码。

第一个解决方案是只在AppDomains上调用代码。你传递的对象必须是“远程”,这可能是一个很大的设置。 (从MarshalByRefObject派生等)不仅如此,传递给AppDomains或来自AppDomains的任何对象都必须是可序列化的。它是可行的,但有时它并不漂亮。

第二种解决方案是使用远程处理。它现在是旧技术,但它仍然有效。它基本上形成了跨AppDomains的上述调用。我在这里不再多说了,我差点把它搞砸了。

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

第三个解决方案是我目前用于类似于您描述的项目的解决方案。我们的目标是隔离数据库,这样我们就可以尝试nHibernate,而不会“污染”其他层。

答案 1 :(得分:0)

我不知道有这样的数据库。

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

  1. 您的数据库应该在自己的应用程序域中运行
  2. 每个客户端都应该在自己的应用域中运行
  3. 应使用应用域之间的标准序列化来返回查询结果。最简单的方法是将查询封装在自己的类中,这些类在构造时执行。这样,您就可以使用AppDomain.CreateInstance
  4. 您的数据库应该能够处理来自任何线程的请求。
  5. 我认为这不是一个好主意。有关应用程序域如何工作和互操作的详细信息太多,无法实现100%正确。