是否可以测试流程的事务性?

发布于 2024-09-28 18:03:36 字数 1109 浏览 2 评论 0原文

我希望能够验证每个工作单元是否在其自己的事务中完成,或者作为单个全局事务的一部分完成。

我有一个方法(使用 spring 和 hibernate 定义),其形式为:

private void updateUser() {
    updateSomething();
    updateSomethingElse();
}

这是从两个地方调用的,用户登录时的网站和每天运行的批处理作业。对于 Web 服务器上下文,它将与 Web 服务器创建的事务一起运行。对于批处理作业,每个用户必须有一个事务,因此如果在此方法期间出现故障,事务将回滚。因此,我们有两个方法:

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void updateUserCreateNewTransaction() {
    updateUser();
}

@Transactional(propagation=Propagation.REQUIRED)
public void updateUserWithExistingTransaction() {
    updateUser();
}

从批处理作业调用 updateUserCreateNewTransaction(),从 Web 服务器上下文调用 updateUserWithExistingTransaction()。

这有效。但是,(批次的)这种行为不被改变是非常重要的,所以我希望创建一个测试来测试这种行为。如果可能的话,我想在不更改代码的情况下完成此操作。

因此,我可以选择的一些选项是:

  1. 计算在 批处理运行期间的数据库 job.

  2. ,以便在 updateSomethingElse() 方法中至少有一个用户更新失败,并检查该用户的 updateSomething() 尚未发生。

  3. 代码审查。

1 是一个非常依赖数据库的方法,我如何保证 hibernate 无论如何都不会创建事务? 2 似乎更好,但设置起来非常复杂。 3 不太实用,因为我们需要为每个版本都执行一个。

那么,有没有人有一种方法可以让我测试这段代码,最好是通过系统测试或集成测试?

I would like to be able to verify if each unit of work is done in its own transaction, or as part of a single global transaction.

I have a method (defined using spring and hibernate), which is of the form:

private void updateUser() {
    updateSomething();
    updateSomethingElse();
}

This is called from two places, the website when a user logs in and a batch job which runs daily. For the web server context, it will run with a transaction created by the web server. For the batch job, it must have one transaction for each user, so that if something fails during this method, the transaction is rolled back. So we have two methods:

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void updateUserCreateNewTransaction() {
    updateUser();
}

@Transactional(propagation=Propagation.REQUIRED)
public void updateUserWithExistingTransaction() {
    updateUser();
}

updateUserCreateNewTransaction() is called from the batch job, and updateUserWithExistingTransaction() from the web server context.

This works. However, it is very important that this behaviour (of the batch) not be changed, so I wish to create a test that tests this behaviour. If possible, I would like to do this without changing the code.

So some of the options open to me are:

  1. Count the transactions opened in the
    database during the run of the batch
    job.

  2. Change the data in some sublte way so that at least one user update fails, in the updateSomethingElse() method, and check that the updateSomething() for that user has not taken place.

  3. Code review.

1 is a very database dependent method, and how do I guarantee that hibernate won't create a transaction anyway?. 2 seems better, but is very complex to set up. 3 is not really practical because we will need to do one for every release.

So, does anyone have a method which would enable me to test this code, preferably through a system test or integration test?

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

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

发布评论

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

评论(2

梦幻的味道 2024-10-05 18:03:36

我会尝试使用内存中的 HSQLDB 和 EasyMock (或其他一些模拟框架)在单元测试工具中设置测试。

然后,您可以让 updateSomething() 方法真正写入 HSQL 数据库,但使用模拟框架来模拟 updateSomethingElse() 方法并抛出 RuntimeException 来自该方法。完成后,您可以对 HSQLDB 执行查询以验证 updateSomething() 内容是否已回滚。

它需要一些管道来设置 HSQLDB 和事务管理器,但是完成后,您就可以进行没有外部依赖项的测试,并且可以随时重新运行。

I would try to setup a test in a unit test harness using an in memory HSQLDB and EasyMock (or some other mocking framework).

You could then have the updateSomething() method really write to the HSQL database but use the mock framework to mock the updateSomethingElse() method and throw a RuntimeException from that method. When that is done you could perform a query against the HSQLDB to verify that the updateSomething() stuff was rolled back.

It will require some plumbing to setup the HSQLDB and transaction manager but when that is done you have a test without external dependencies that can be re-run whenever you like.

扬花落满肩 2024-10-05 18:03:36

您可以做的另一件事是配置 Hibernate 事务的日志输出:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#configuration-logging

如果您为 org. hibernate.transaction 具有跟踪日志级别,它应该告诉 Hibernate 在单元测试期间以事务方式执行的所有操作。

Another thing you can do is configure logging output for Hibernate's transactions:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#configuration-logging

If you make a log4j category for org.hibernate.transaction with trace log leve, it should tell everything that Hibernate does transaction-wise during a unit test.

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