Spring JMS 测试和事务回滚

发布于 2024-12-08 15:25:38 字数 558 浏览 0 评论 0原文

我有一个使用 Spring 的 SpringJUnit4ClassRunner 的测试工具(它在每个 JUnit 测试结束时自动回滚数据库更新)。现在我想测试我的基于 Spring 的 JMS 代码:

  1. 创建了一些数据库项
  2. 发送 JMS 消息来执行某些操作
  3. MDP 接收该消息并在数据库中执行其他操作

测试中实际发生的情况如下:

  1. Spring在线程 1 上开始事务 (tx1)
  2. 在 tx1 上下文中创建数据库项
  3. 发送 JMS 消息
  4. 事务 tx1 回滚,线程 1 退出
  5. 线程 2 启动 MDP,开始事务 tx2,读取消息,数据库工作
  6. 线程 2 提交 tx2,因为它没有由测试工具启动,然后退出

我想要发生的是 tx1 和 tx2 都由 SpringJUnit4ClassRunner 控制,所以我得到了自动回滚。如果他们能够共享相同的整体事务上下文,那就更好了;现在,如果 tx1 中保存了某些内容,即使线程 1 没有回滚该 tx,tx2 也不会看到数据库更改。

I have a test harness using Spring's SpringJUnit4ClassRunner (which automatically rolls back DB updates at the end of each JUnit test). Now I want to test my Spring-based JMS code:

  1. Some DB item is created
  2. A JMS message is sent to do something
  3. The MDP picks up the message and does something else in the DB

What is actually happening in the Test is the following:

  1. Spring begins the transaction (tx1) on thread 1
  2. The DB item is created in the tx1 context
  3. The JMS message is sent
  4. Transction tx1 is rolled back and thread 1 exits
  5. Thread 2 spins up the MDP, begins transaction tx2, reads the message, and does DB work
  6. Thread 2 commits tx2, as its not spun up by the test harness, and exits

What I want to have happen is for tx1 and tx2 to both be controlled by SpringJUnit4ClassRunner so I get the automatic rollback. Even better would be if they could share the same overall transactional context; right now, if something is saved in tx1, even if Thread 1 hasn't rolled back that tx, tx2 doesn't see the DB changes.

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

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

发布评论

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

评论(1

熊抱啵儿 2024-12-15 15:25:38

您需要使用支持 XA 的事务管理器,从而能够对数据库和 JMS 引擎进行两阶段提交。有几个这样的交易管理器(Bitronix、Atomikos 等)可以免费使用。

如果您已经使用这样的事务管理器(因为您的应用程序在提供它的应用程序服务器中运行),但您不想仅为单元测试配置如此繁重的东西,那么请实现两个单元测试,

  • 其中一个是模拟 JMS 部分的up(仅测试数据库项创建),
  • 以及仅测试 JMS 消息处理的情况

请注意,如果没有 XA,您可能必须处理处理 JMS 消息而第一个事务尚未提交的奇怪情况,或者提交数据库事务的地方,但是消息发送失败。

You need to use a transaction manager that supports XA, and is thus able to do a two-phase commit on the database and the JMS engine. There are several such transaction managers (Bitronix, Atomikos, etc.) freely available.

If you already use such a transaction manager (because your app runs in an application server providing it), but you don't want to configure something as heavy just for the unit tests, then implement two unit tests

  • one where the JMS part is mocked up (to test the DB item creation only),
  • and one where only the JMS message handling is tested

Note that without XA, you'll probably have to handle bizarre situations where the JMS message is handled whereas the first transaction is not committed yet, or where the database transaction is comitted but the sending of the message fails.

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