内存数据库可跨 AppDomain 边界使用

发布于 2024-08-03 06:33:49 字数 919 浏览 6 评论 0原文

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

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

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

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

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

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

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

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

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

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

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

PS

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

I wonder if there is an in-memory database implementation, where the same in-memory database instance can be used across multiple AppDomains.

The motivation. Like many folks out there, we have integration tests for our client-server application. There are several test modes, from the most heavy one - the real life scenario, where the client, server and database are all located on different machines to the most lightweight one, where both the client and server are simply two AppDomains in the same process and the database is an sqlite file on the same machine.

Naturally, the lightweight scenario is the fastest and developers routinely use it, while the heavy one is run on our CI server on each build.

My goal is to further speed up the lightweight scenario by using an in-memory database.

The problem. OK, so sqlite has an in-memory database option, but such a database:

  • is disposed of after a connection to it is closed.
  • cannot have two open connections, new connections open another database instance.

Unfortunately, I need two - one for the test staging code, which runs in the client side AppDomain and the other - for the server side DAL.

I realize the rationale behind the way sqlite in-memory database works. I am also aware of the difficulties of having in-memory database shared between two AppDomains. How can one share a memory buffer between two AppDomains without reverting to memory mapped files (and I do not want to deal with any File System API)?

The only efficient solution that I see is having two AppDomains share an unmanaged memory buffer, where the handle to the buffer would be passed from one AppDomain to another. But are there any in-memory database implementations that support this setup?

(An inefficient solution would be to pass the whole database from one AppDomain to another and then back again).

I may be completely wrong with my analysis and there may be simple solutions which I miss. Anyway, I would like to know if anyone has encountered the same problem and how have they solved it.

P.S.

I would really like to avoid any kind of File API, like memory mapped files.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薯片软お妹 2024-08-10 06:33:49

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

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

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

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

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

I have three solutions that come to mind, but all of them require some configuration. They all require you to create a third AppDomain where the in-memory database resides as a s singleton, and to code a class with a well-defined interface to this database.

The first solution is to just call code across AppDomains. The objects you pass must be "Remotable" which can be a big deal to set up. (Derive from MarshalByRefObject, etc) Not only that, any objects you pass to or from the AppDomains must be serializable. It's do-able, but sometimes it's not pretty.

A second solution is to use remoting. It's old technology now, but it still works. It basically formalizes the above call across AppDomains. I won't say any more about it here, I'm almost embarrassed by bringing it up.

A third solution is to use WCF and the namedPipeBinding which is fast. Both ends of a WCF call can be in the same applicaton and in different app domains. A side effect of coding it this way is that you'd be able to switch out the in-memory database for the fully featured one later, and change the binding to work across an intranet, or the internet.

The third solution is the one I'm currently using for a project similar to what you describe. Our goal was to isolate the database so we could try out nHibernate without "contaminating" the rest of the layers.

锦上情书 2024-08-10 06:33:49

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

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

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

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

I don't know of any such database.

But it's fun to think about what form such a database could have. If we consider an app domain a light-weight process, then we can treat cross-domain talking (serialization) as message passing. Then we can define a simple message protocol that allows clients to send queries, and in response get results.

  1. Your database should run in its own app domain
  2. Each client should run in its own app domain
  3. Standard serialization between app domains should be used to return query results. The easiest way to do that is to encapsulate queries in their own classes that execute when constructed. That way, you can use AppDomain.CreateInstance.
  4. Your database should be able to handle requests from any thread.

I don't think this is a great idea though. There are too many details in how app domains work and interoperate to get this 100% right.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文