1

我们在数据库表上遇到了一些规律性争用,并想评估一些不同的选项来解决这个问题。

为此,我需要在测试用例中重现具有可重复可靠性的表(任何表)上的争用。

我正在考虑的方法是反转锁的语义(例如java.util.concurrent.locks.ReentrantLock)并在表上开始写入时释放锁,允许所有读取在写入开始时发生。

因此,一个写入器线程持有锁,直到在对表执行插入操作之前不久,然后释放锁,多个读取器线程将尝试对同一个表运行选择语句。

想知道是否对这种方法有任何想法,或者是否有一种更简单的方法可以以 100% 的可靠性重现数据库表上的争用。

谢谢

4

2 回答 2

2

您可以使用计数为 的 CountDownLatch 1

final CountDownLatch barrier = new CountDownLatch(1);

您启动所有阅读器线程,其第一个操作是

barrier.await();

那么作家线程可以

barrier.countDown();

在这一点上,所有的读者都会愉快地开火。

于 2009-12-16T18:01:29.363 回答
0

在数据库中产生争用的难易程度很大程度上取决于您的数据库。例如,如果您使用的是 Oracle,那么执行 select 将永远不会产生任何争用。

在数据库中产生争用的最简单方法是在您知道您将需要更新的行上执行 select for read。

编辑:重新阅读问题后,我发现您似乎更关心数据库上的“读者”争用而不是更新争用。上面的想法可以用来强制更新争用,而不是读者争用。

在这种情况下,如果您想启动大量读者以使用选择淹没数据库,这应该不会导致实际争用,只会导致饥饿,那么您可以使用另一个答案中提到的 CountDownLatch ,或者以老式方式进行如果您被迫在 1.5 之前的 JVM 中运行,请使用 Object.wait/Object.notifyAll()。

编辑 2:阅读评论后,模拟您所看到的争用的最简单方法可能是使用 Sybase lock table 命令。只需锁定表,启动选择,然后解锁表。然后选择应该全部触发......这还具有最准确地模拟您尝试建模的情况的优势。

于 2009-12-16T20:15:10.130 回答