冬眠:尽管有@transactional

发布于 2025-01-23 17:38:56 字数 1244 浏览 0 评论 0原文

我们有一个大型应用程序,使用Spring进行应用程序设置,初始化和“接线”和Hibernate作为持久框架。对于该应用程序,我们进行了几个单位测试,这会引起我们的头痛,因为它们在我们的Jenkins Build Server上执行时一次又一次地运行“红色”。

这些Unitests执行并验证了我们应用程序的一些相当复杂且冗长的核心操作,因此我们认为它太复杂了,太多的努力无法嘲笑DB。相反,这些UTS与真实的DB相反。在执行UTS之前,我们创建所需的对象(“预先条件”)。然后我们运行测试,然后验证某些对象的创建,其状态和价值等。所有纯香草...

由于我们按顺序运行多个测试,所有测试都需要相同的起点这些测试,这些测试来自一个普通的父母类,具有@transactional注释。这样做的目的是,在每个单位测试后,DB总是回滚,以便后续测试可以从相同的基线开始。

在“本地”执行单位测试时(即在开发人员的工作站上运行“ MVN验证”)时,这种方法正常可靠地工作。但是,当我们在詹金斯上执行相同的测试时,这些测试并非总是如此 - 这些测试失败了,因为在测试后发现过多的对象或由于违反约束,因为某些对象已经存在在那里。 正如我们通过添加 lot 日志仪式(因为否则不可能在Jenkins上运行代码)的原因是,这些失败的原因是,在事先测试后,DB偶尔无法正确回滚。因此,DB中先前的测试中有剩下的剩余,然后在随后的测试中引起问题。

最困惑的是: 为什么只有在我们在詹金斯上执行它们时,这些测试才会失败,但是当我们在本地运行相同的测试时,这些测试从来没有失败?我们在此处使用绝对相同的Maven命令行和代码,也是相同的Java版本,Maven版本等。

我们现在确定这与我们最初怀疑的UTS并行执行无关。我们禁用所有选项以并行运行UTS,这是Maven Surefire插件提供的。我们的日志仪器还清楚地表明,测试是完美序列化的,但一次又一次地“堆积”,即在每个测试方法之后,这些对象的数量本来应该在测试,仍然存在,每个测试的数量增加。

我们还观察到具有这种效果的某种“随机性”。通常,詹金斯(Jenkins)构建了几个提交的运行良好,然后突然(即使没有任何代码更改,也可以通过重新验证同一分支的新构建)开始运行红色。但是,数据库在每个构建& amp;测试运行,因此不能成为这种效果的来源。

知道有人会导致这一点吗?为什么应该由@org.springframework.transaction.annotation.transactional.transactional注释在我们的笔记本电脑上可靠但在我们的构建服务器上不可靠,但在我们的构建服务器上不起作用?任何人都有类似的经历和发现吗?

We have a large application using Spring for application setup, initialisation and "wiring" and Hibernate as persistence framework. For that application we have a couple of unit tests which are causing us headaches because they again and again run "red" when executing them on our Jenkins build server.

These UnitTests execute and verify some rather complex and lengthy core-operations of our application and thus we considered it too complex and too much effort to mock the DB. Instead these UTs run against a real DB. Before the UTs are executed we create the objects required (the "pre-conditions"). Then we run a Test and then we verify the creation of certain objects, their status and values etc. All plain vanilla...

Since we run multiple tests in sequence which all need the same starting point these tests derive from a common parent class that has an @Transactional annotation. The purpose of that is that the DB is always rolled back after each unit-test so that the subsequent test can start from the same baseline.

That approach is working perfectly and reliably when executing the unit-tests "locally" (i.e. running a "mvn verify" on a developer's workstation). However, when we execute the very same tests on our Jenkins, then - not always but very often - these tests fail because there are too many objects being found after a test or due to constraint violations because certain objects already exist that shouldn't yet be there.
As we found out by adding lots of log-statements (because it's otherwise impossible to observe code running on Jenkins) the reason for these failures is, that the DB is occasionally not properly rolled back after a prior test. Thus there are left-overs from the previous test(s) in the DB and these then cause issue during subsequent tests.

What's puzzling us most is:
why are these tests failing ONLY when we execute them on Jenkins, but never when we run the very same tests locally? We are using absolute identical maven command line and code here, also same Java version, Maven version, etc.

We are by now sure that this has nothing to do with UTs being executed in parallel as we initially suspected. We disabled all options to run UTs in parallel, that the Maven Surefire plugin offers. Our log-statements also clearly show that the tests are perfectly serialized but again and again objects "pile up", i.e. after each test-method, the number of these objects that were supposed to have been removed/rolled back at the end of the test, are still there and their number increases which each test.

We also observed a certain "randomness" with this effect. Often, the Jenkins builds run fine for several commits and then suddenly (even without any code change, just by retriggering a new build of the same branch) start to run red. The DB, however, is getting re-initialized before each build & test-run, so that can not be the source of this effect.

Any idea anyone what could cause this? Why do the DB rollbacks that are supposed to be triggered by the @org.springframework.transaction.annotation.Transactional annotation work reliable on our laptops but not on our build server? Any similar experiences and findings on that anyone?

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文