我通常确切地知道哪个并发查询可能会引起问题,但是我不知道如何强制它们同时运行,以查看是否发生了正确的行为(例如,我使用了正确的锁类型),抛出了正确的错误等。
注意:我使用PostgreSQL和Perl,因此,如果不能一概而论,就应该重新标记。
更新:如果解决方案是编程的,我希望这样做。这样,我可以编写自动化测试以确保没有回归。
#1 楼
我一直在用T-SQL模块来做。本质上,您需要做的就是从两个或多个连接中循环运行模块几分钟。通常,假设您有一个带有不错CPU的SQL Server盒,那么所有潜在问题都会在几分钟之内暴露出来。
我在这里和这里写了一些例子。
#2 楼
我通常使用RDBMS的命令行工具,只是启动了2个(或更多)CLI实例。然后,您可以一个接一个地重放您的应用程序层正在发送的SQL语句,作为竞赛(看起来像一个动作RPG)。您应该尝试/感觉锁系统的作用,因为您的CLI会“挂起”,等待锁从其他CLI释放。
如果听起来像泥泞,毫不犹豫地说;-)
评论
您可以举一个逐步的例子吗?可以编写程序测试来做同样的事情吗?
– xenoterracide
2011年1月6日13:20
#3 楼
竞争条件需要多个执行线程,因此要进行单元测试,您将需要能够启动一个或多个线程。在Oracle中,我将使用DBMS_Scheduler运行一个过程来模拟第二个用户。如果PostgreSQL / Perl能够以编程方式启动第二个进程,那么您应该可以执行以下操作:进程1进程32
很高兴看到关于如何处理比赛条件的思考,更重要的是如何对它们进行单元测试。
评论
我不会将这种测试描述为单元测试,因为单元测试每次都必须以完全相同的方式运行。竞争条件会间歇地使涉及的过程失败,而不是每次都以完全不同的方式失败。
–A-K
2012年3月29日在2:41
@AlexKuznetsov您是正确的,意外的竞争条件会间歇性地显示它们,但是OP指的是他认为代码正在处理的预期条件。这些特定条件可以精确再现,并通过单元测试验证处理方式。
–雷·里菲尔(Leigh Riffel)
2012年3月29日14:19
#4 楼
只要锁定行,就不会遇到通常没有锁定就导致的竞争状态。但是,如果一个问题阻塞您的问题的时间过长,您可能会陷入僵局。
/>
这很难测试,因为随着数据库的增长查询时间会改变。
对10万行测试数据有效的查询在图表中就没有1000万行。
这种类型的问题可能很难预先发现,但是许多DB都有一些识别慢查询的方法。
通过定期使用这种方法,您应该能够如果有任何警告,则会陷入麻烦。
如果您自己锁定,那是另一回事了,但是我无能为力。
评论
@darioo大声笑我以为wn是某事的首字母缩写…idk他的意思是“自己锁定”。如果他的意思不是使用ORM,则我检查了我的ORM输出的代码,它肯定不会执行锁定权。这就是我希望能够测试潜在比赛条件场景的原因之一。
– xenoterracide
2010-11-29 2:15
是的,我的意思是自己的,通常数据库驱动程序会处理锁定,行,表或可能的字段,但是我只是在开放您使用某些不处理锁定的数据库的可能性;)
– DavidMårtensson
2010-11-29 13:17
..我很确定我是否有一个多语句事务,我的数据库将不知道要自动锁定哪些行...如果选择了行,则不会选择select for update这样的事情...
– xenoterracide
2010-12-5 10:05
评论
“种族条件”是指“僵局”吗?@Gaius ...尽管我确实认为这是某些比赛条件的可能结果
数据库中的@Gaius竞争条件将进行一些操作,例如在创建表之前删除表或在插入表之前更新行。通常,我会想象它是由数据库本身之外的应用程序逻辑处理的。
在插入之前更新行?那不会导致数据库问题。没有竞争条件就像获取一行并对其进行更新,而是让另一个用户在获取该行之后但在处理更新之前对其进行更新。
@MarkD-否。错误地将原子工作单元封装到数据库中会导致多种竞争状况。这是一个例子。请记住,“比赛条件或比赛危险是电子系统或过程中的缺陷,在此过程中,过程的输出或结果出乎意料地严重依赖于其他事件的顺序或时间。” (来源)