2009-12-16 2 views
1

Nous expérimentons avec un conflit de régularité sur une table de base de données, et nous souhaitons évaluer un certain nombre d'options différentes pour résoudre ce problème. Pour ce faire, j'ai besoin de reproduire dans un cas de test, une contention sur une table (n'importe quelle table) avec une fiabilité reproductible. L'approche que je considère serait d'inverser la sémantique d'un verrou (par exemple java.util.concurrent.locks.ReentrantLock) et de libérer le verrou lorsque l'écriture sur la table commence, permettant à toutes les lectures de se produire au moment où l'écriture commence. Par conséquent, un thread d'écriture maintient le verrou jusqu'à peu avant d'insérer une insertion dans une table et libère ensuite le verrou, plusieurs threads de lecture tentant d'exécuter des instructions select sur la même table. Je me demandais s'il y avait des idées sur une telle approche, ou s'il y a une approche plus simple qui pourrait, avec une fiabilité de 100%, reproduire la contention sur une table db.Nous reproduisons de façon fiable la contention db

grâce

Répondre

2

Vous pouvez utiliser un CountDownLatch avec un compte de 1.

final CountDownLatch barrier = new CountDownLatch(1); 

Vous lancez tous les fils de lecture, dont première action est

barrier.await(); 

alors le fil écrivain peut

barrier.countDown(); 

à quel point tous les lecteurs se déclenche joyeusement.

+0

bonne idée! en donnant un coup de feu .... –

+0

fonctionne comme un charme :-) –

+0

Awesome. Content de l'entendre. –

0

Cela dépend beaucoup de votre base de données quant à la facilité de générer des conflits. Par exemple, si vous utilisez Oracle, la sélection ne produira jamais de conflit. La méthode la plus simple pour générer un conflit dans la base de données consiste à sélectionner une lecture sur la ligne dont vous savez qu'elle doit être mise à jour.

Modifier: Après avoir relu la question, je vois que vous semblez vous soucier plus de la contention "lecteur" sur la base de données que la mise à jour contention. L'idée ci-dessus peut être utilisée pour forcer la contention de la mise à jour, mais pas la contention du lecteur. Dans le cas où vous voulez lancer un nombre en masse de lecteurs pour inonder la base de données avec des sélections, ce qui ne devrait provoquer aucun conflit réel, seulement la famine, alors vous pouvez utiliser le CountDownLatch comme mentionné dans une autre réponse, ou le faire à l'ancienne avec Object.wait/Object.notifyAll() si vous devez exécuter une JVM antérieure à la version 1.5.

Edit 2: Après avoir lu le commentaire, sans doute la meilleure façon d'imiter l'affirmation que vous voyez est d'utiliser le Sybase lock table command. Verrouillez simplement la table, lancez les sélections, puis déverrouillez la table. Les sélections devraient alors tous se déclencher ... cela a aussi l'avantage d'émuler le plus précisément la situation que vous essayez de modéliser.

+0

merci pour votre réponse! La contention que nous voyons (dans Sybase d'ailleurs) est quand une insertion énorme est faite à une très grande table avec beaucoup d'index là-dessus.Pendant que cette insertion est en cours, plusieurs sélections sont en attente tandis que Sybase verrouille la table entière, ainsi que l'espace d'index. –

+0

c'est une approche intéressante, et je vais regarder. Cependant, une partie de ce que nous essayons d'analyser est de savoir comment les changements aux écritures affecteront la contention. De plus, nous constatons que souvent, il utilise le verrouillage au niveau de la ligne, mais il verrouille l'index entier de sorte que l'écriture est rapide, mais le txn est maintenu par le verrou maintenu pendant la mise à jour des index. –

+0

Hmm ... Juste perdu le upvote pour ajouter plus d'informations à ma réponse? –

Questions connexes