2010-12-15 4 views
0

Ich habe folgende Implementierung in Java, wo ich eine synchronisierte Methode zu verwenden, versuchen:Problem mit synchronisierten Methode in Java

class dbAccess{ 
    public synchronized void getGUID(){ 
      counter=/*Access last count from txn_counter table */ 
      /*Insert a unique value to txn_counter table based on the acquired value of counter */ 
      /*Insert new counter value to GUID_log table */ 
    } 
} 

Der Abschnitt zwischen/* */einigen SQL-Abfragen darstellen. Die Implementierung hat 10 Threads. Ich hatte gehofft, dass der Rückgabewert jedes Mal einmalig sein würde. Es kommt jedoch vor, dass mehrere Läufe den gleichen Wert des Zählers zurückgeben.

Können Sie bitte darauf hinweisen, wenn ich etwas falsch mache. Und ist es der richtige Weg, dies zu tun?

Antwort

3

Vielleicht haben Sie mehrere Instanzen von dbAccess? (Das Schlüsselwort synchronized funktioniert auf Objektebene nicht auf Klassenebene.) In diesem Fall müssen Sie die Methode statisch machen (in Ihrer Situation möglicherweise nicht möglich) oder versuchen, eine statische Sperre zu erstellen, die den Methodenrumpf schützt:

class dbAccess{ 
    private final static Object o = new Object(); 

    public void getGUID(){ 
     synchronized (o) { 
      counter=/*Access last count from txn_counter table */ 
      // Insert a unique value to txn_counter table based on 
      // the acquired value of counter 
      // Insert new counter value to GUID_log table 
     } 
    } 
} 
class dbAccess{ 
    private final static Object o = new Object(); 

    public void getGUID(){ 
     synchronized (o) { 
      counter=/*Access last count from txn_counter table */ 
      // Insert a unique value to txn_counter table based on 
      // the acquired value of counter 
      // Insert new counter value to GUID_log table 
     } 
    } 
} 
+0

Vielen Dank, dass Sie auf das Problem mehrerer Instanzen von dbAccess hingewiesen haben. Das war, was ich tat. Jetzt versuche ich, es als statische Methode zu implementieren, wie Sie vorschlagen. Ich hoffe, das funktioniert für mich. – jitendra

5

Nur weil es in Java synchronisiert wird, heißt das nicht, dass es in der Datenbank synchronisiert ist. Diese Methode muss in einer Datenbanktransaktion mit aktivierter Lesesperre ausgeführt werden.

+2

Der wichtigste Teil der Ausführung einer Transaktion besteht darin, dass der geänderte Wert in txn_counter an die Datenbank übergeben werden muss, bevor der nächste Thread die "letzte Zählung von txn_count" liest. –

+0

Dies ist ein guter Rat, aber wenn die Datenbank für die Anwendung bestimmt ist und es nur eine Instanz der Anwendung gibt, und er diese Änderungen tatsächlich im db-Code festlegt, dann würde die Synchronisation in der Anwendung funktionieren. Natürlich wäre es aufgrund der Voraussetzungen, die erfüllt werden müssen, eher fragil. –

+0

@Tim, meine Datenbank und Anwendung treffen die Situation, die Sie beschreiben. Die Datenbank ist für die Anwendung reserviert und es wird nur eine Instanz der Anwendung ausgeführt. Und ich habe versucht, den Datenbankzugriffsteil von der Anwendung zu synchronisieren. Ich hoffte, dass es beim Lesen und Schreiben in die Datenbank Sperren erhalten würde. – jitendra