我们在数据库表上遇到一些规律性争用,并且想要评估解决此问题的许多不同选项。
为了做到这一点,我需要在一个测试用例中重现,在一个表(任何表)上争用可靠性。
我正在考虑的方法是反转锁的语义(例如java.util.concurrent.locks.ReentrantLock
)并在开始写表时释放锁定,允许所有读取在写入开始时发生。
因此,一个编写器线程持有锁直到插入表之前不久,然后释放锁,多个读取器线程将尝试对同一个表运行select语句。
想知道是否有任何关于这种方法的想法,或者是否有一种更简单的方法可以100%可靠地重现db表上的争用。
感谢
答案 0 :(得分:2)
您可以使用CountDownLatch,其计数为1
。
final CountDownLatch barrier = new CountDownLatch(1);
启动所有读取器线程,其第一个操作是
barrier.await();
那么编写者线程可以
barrier.countDown();
此时所有的读者都会欢快地离开。
答案 1 :(得分:0)
您的数据库在很大程度上取决于在其中产生争用是多么容易。例如,如果您使用的是Oracle,那么执行select将永远不会产生任何争用。
在数据库中产生争用的最简单方法是对您知道需要更新的行执行select选择。
编辑:重新阅读问题之后,我发现您似乎更关心数据库上的“读者”争用而不是更新争用。上述想法可用于强制更新争用,但不能用于读者争用。
在这种情况下,如果你想启动大量的读者来使用选择来充满数据库,这应该不会引起实际争用,只会导致饥饿,那么你可以使用另一个答案中提到的CountDownLatch,或者这样做如果您被迫在1.5之前的JVM中运行,则使用Object.wait / Object.notifyAll()的旧式方法。
编辑2 :阅读评论后,模拟您所看到的争用的最简单方法可能是使用Sybase lock table command。只需锁定表格,启动选择,然后解锁表格。然后选择应该全部启动...这也具有最准确地模拟您试图建模的情况的优势。