您如何测试数据库中的竞争条件?


30

我尝试编写数据库代码以确保它不受争用条件的影响,以确保锁定了正确的行或表。但是我经常想知道:我的代码正确吗?是否可以强迫任何现有的竞赛条件表现出来?我想确保,如果它们确实发生在生产环境中,我的应用程序将做正确的事情。

我通常确切地知道哪个并发查询可能会导致问题,但是我不知道如何强制它们并发运行以查看是否发生了正确的行为(例如,我使用了正确的锁类型),正确的错误是抛出等

注意:我使用PostgreSQL和Perl,因此,如果不能一概而论,就应该重新标记它。

更新:如果解决方案是程序化的,我希望使用它。这样,我可以编写自动化测试以确保没有回归。


“种族条件”是指“僵局”吗?
Gaius

2
@Gaius ...尽管我不相信这是某些比赛条件的可能结果
xenoterracide 2011年

数据库中的@Gaius竞争条件将进行一些操作,例如在创建表之前删除表或在插入表之前更新行。通常,我会想象它是由数据库本身之外的应用程序逻辑处理的。
Mark D

在插入之前更新一行?那不会导致数据库问题。任何竞争条件都不会像获取行并进行更新,而是让另一个用户在获取行之后但未处理更新之前对其进行更新。
xenoterracide 2012年

1
@MarkD-否。错误地将原子工作单元封装到数据库中会导致多种竞争状况。 这是一个例子。请记住,“比赛条件或比赛危险是电子系统或过程中的缺陷,在此过程中,过程的输出或结果出乎意料地严重依赖于其他事件的顺序或时间。” (消息来源
Nick Chammas 2012年

Answers:


11

我一直在用T-SQL模块来做。

本质上,您需要做的就是从两个或多个连接中循环运行模块几分钟。通常,假设您有一个带有适当CPU的SQL Server盒,那么所有潜在问题都会在几分钟之内暴露出来。

在这里这里写了一些例子。


4

我通常使用RDBMS的命令行工具,只是启动了2个(或更多)CLI实例。然后,您可以一个接一个地重放您的应用程序层正在发送的SQL语句,作为竞赛(看起来像一个动作RPG)。您应该尝试/感觉一下正在使用的锁定系统,因为CLI会“挂起”一点,等待其他CLI释放锁定。

如果听起来像泥泞,请毫不犹豫地说;-)


您可以举一个逐步的例子吗?可以编写程序测试来做同样的事情吗?
xenoterracide 2011年

1

竞争条件需要多个执行线程,因此要进行单元测试,您将需要能够启动一个或多个线程。在Oracle中,我将使用DBMS_Scheduler运行一个过程来模拟第二个用户。如果PostgreSQL / Perl可以以编程方式启动第二个进程,那么您应该能够执行以下操作:

过程1过程2

启动过程2。>>                            
延迟允许2个执行它的工作。 
。锁定行或更改数据。
。延迟允许1进行工作。
尝试锁定行或更改数据。。
检查以确保正确处理。。
结束 。
                                                结束

很高兴看到关于如何处理比赛条件的思考,更重要的是如何对它们进行单元测试。


我不会将这种测试描述为单元测试,因为每次单元测试都必须以完全相同的方式运行。竞争条件会间歇地使涉及的过程失败,而不是每次都以完全不同的方式失败。
AK

@AlexKuznetsov您是正确的,意外的竞争条件会间歇性地显示它们,但是OP指的是他认为代码正在处理的预期条件。这些特定条件可以精确再现,并且通过单元测试可以验证操作。
Leigh Riffel 2012年

-2

只要锁定行,就不会出现竞争状况,因为通常情况是在没有锁定的情况下引起的。

但是,如果一个问题阻塞您的问题的时间过长,您可能会陷入僵局。

这很难测试,因为随着数据库的增长查询时间会改变。

可以很好地处理10万行测试数据的查询,排在图表的前10万行。

这种类型的问题可能很难预先发现,但是许多DB都有识别慢查询的某种方法。

通过定期使用该规则,您应该能够以充分的警告捕获所有陷入麻烦的查询。

如果您自己锁定,那就另当别论了,但是我无能为力。


@darioo大声笑我以为wn是某事的首字母缩写…idk他的意思是“自己锁定”。如果他的意思不是使用ORM,则我检查了我的ORM输出的代码,它肯定不会执行锁定权。这就是我希望能够测试潜在比赛条件场景的原因之一。
xenoterracide 2010年

是的,我的意思是拥有者,通常数据库驱动程序会处理锁定,行,表或可能的字段,但我只是在开放您使用某些无法处理锁定的数据库的可能性;)

..我非常确定我是否有一个多语句事务,我的数据库将不知道要自动锁定哪些行... select for update如果这样的话就不会存在...
xenoterracide 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.