[JAVA] Versuchen Sie, ScalarDB unter WSL Ubuntu auszuführen (Beispiel-App-Erstellung)

In diesem Artikel geht es um das Erstellen einer Beispiel-App. Lassen Sie uns die Beispiel-App von ScalarDB ausführen.

Klicken Sie hier, um die Umgebung zu erstellen (https://qiita.com/XCAT_SE/private/07969c960fb776d78990).

ScalarDB-Operation

Für ScalarDB gibt es zwei Betriebskomponenten: die Speicherkomponente und die Transaktionskomponente.

Speicherkomponente

Diese Komponente hat die folgenden Funktionen.

Darüber hinaus entspricht die Rolle des Schlüssels hier dem Partitionsschlüssel und dem Clustering-Schlüssel von Cassandra, und mehrere Definitionen können in Form einer Liste oder durch Kommas getrennt vorgenommen werden.

Darüber hinaus bietet die ScalarDB-Speicherkomponente vier Funktionen für CRUD-Operationen.

Transaktionskomponente

Diese Komponente bietet zusätzlich zur Funktionalität der Speicherkomponente masterlose Transaktionsfunktionen.

Um die Transaktionsfunktion verwenden zu können, müssen Sie zunächst eine TransactionService-Instanz abrufen. Nachdem Sie die Operationen Get, Put, Delete und Scan für die TransactionService-Instanz ausgeführt haben, schreiben Sie die TransactionService-Instanz fest und geben Sie die Operationsdetails in der Datenbank wieder.

Beispiel App

Überprüfen Sie den Betrieb der tatsächlichen Anwendung von ScalarDB mit der Beispielanwendung.

App Übersicht

Implementieren Sie eine Beispiel-App mit diesen Funktionen.

image.png Bilddiagramm

Schemadefinition

image.png

KEYSPACE:emoney TABLE:account Säule ・ Group_id: Gruppen-ID (Partitionsschlüssel) -Id: Benutzer-ID (Clustering-Schlüssel) ・ Guthaben: Geldbetrag, der dem Benutzer gehört

Prozessablauf

aufladen

  1. Informationen zum angegebenen Benutzer abrufen
  2. Fügen Sie den Gebührenbetrag zu den erfassten Benutzerinformationen hinzu
  3. Schreiben Sie die aktualisierten Informationen

Führen Sie die oben genannten Vorgänge innerhalb einer Transaktion aus.

Zahlung

  1. Informieren Sie sich über Absender und Ziel
  2. Vergewissern Sie sich, dass der Saldo der Überweisungsquelle größer als der Überweisungsbetrag ist
  3. Verringern Sie den vom Absender gesendeten Betrag und den an den Empfänger gesendeten Betrag
  4. Schreiben Sie die aktualisierten Informationen

Führen Sie die oben genannten Vorgänge innerhalb einer Transaktion aus.

Kontostand prüfen

  1. Holen Sie sich alle Benutzerinformationen
  2. Extrahieren Sie Benutzerinformationen nacheinander durch Schleifenverarbeitung
  3. Holen Sie sich das Guthaben aus den Benutzerinformationen und zeigen Sie es auf der Konsole an

Umgebung

Angenommen, die für den Betrieb erforderliche Anwendung wurde bereits installiert, verwenden Sie gradle, um die Ausführungs-JAR-Datei abzurufen.

  1. Legen Sie den Pfad zu Scalar DB Schema Tools fest

・ Reflektieren Sie die Einstellungsänderung $ source ~/.bash_profile

  1. Festlegen des Verzeichnisses für das Beispielprojekt

・ Erstellen und verschieben Sie ein Verzeichnis $ mkdir ~/scalardb_sample $ cd ~/scalardb_sample

  1. Erstellen Sie eine Gradle-Definitionsdatei $ vi build.gradle

build.gradle


#Ändern Sie die Spezifikation von mainClassName(18. Zeile)
#Vorher ändern
mainClassName = 'App'
#Nach der veränderung
mainClassName = 'sample.emoney.ElectronicMoneyMain'
#Skalare DB-Definition zu Abhängigkeiten hinzugefügt(22. Zeile)
dependencies {
// This dependency is found on compile classpath of this component and consumers.
compile 'com.google.guava:guava:23.0'
compile group: 'com.scalar-labs', name: 'scalardb', version: '1.0.0'
// Use JUnit test framework
testCompile 'junit:junit:4.12'
  1. Holen Sie sich die Ausführungs-JAR-Datei mit Gradle $ gradle build

OK, wenn BUILD SUCCESS FUL angezeigt wird

Implementierung

  1. Erstellen Sie eine Schemadatei $ vi emoney.sdbql

emoney.sdbql


REPLICATION FACTOR 1;
CREATE NAMESPACE emoney;
CREATE TRANSACTION TABLE emoney.account (
 group_id TEXT PARTITIONKEY,
 id TEXT CLUSTERINGKEY,
 balance INT,
);
  1. Erstellen Sie mit dem Schema-Tool ein Schema in Casssandra $ $SCHEMATOOL/loader emoney.sdbql

Überprüfen Sie das Schema mit cqlsh $ cqlsh

Stellen Sie sicher, dass sich im Schlüsselbereich Emoney befindet cqlsh> DESCRIBE KEYSPACES ;

Ausführungsergebnis


emoney system_auth coordinator system_traces
system_schema system system_distributed

Stellen Sie sicher, dass in der Tabelle ein Konto vorhanden ist cqlsh> use emoney; cqlsh:emoney> DESCRIBE TABLES ;

Ausführungsergebnis


account

Beenden Sie cqlsh cqlsh:emoney> exit

Erstellen Sie zwei, eine Klassendatei, die den Konstruktor und die Funktion beschreibt, und eine Ausführungsklassendatei, die Argumente empfängt und die Funktion aufruft.

Erstellen Sie ein Verzeichnis und eine Java-Datei $ mkdir -p src/main/java/sample/emoney $ cd src/main/java/sample/emoney $ vi ElectronicMoney.java

ElectronicMoney.java


package sample.emoney;

//Import hinzufügen
import com.google.inject.Guice; 
import com.google.inject.Injector; 
import com.scalar.database.config.DatabaseConfig; 
import com.scalar.database.service.StorageModule; 
import com.scalar.database.service.StorageService; 
import com.scalar.database.service.TransactionModule; 
import com.scalar.database.service.TransactionService; 

import java.io.File; 
import java.io.IOException; 

import com.scalar.database.api.DistributedTransaction; 
import com.scalar.database.api.Get; 
import com.scalar.database.api.Put; 
import com.scalar.database.api.Delete; 
import com.scalar.database.api.Result; 
import com.scalar.database.io.IntValue; 
import com.scalar.database.io.Key;
import com.scalar.database.io.TextValue; 
import com.scalar.database.exception.storage.ExecutionException; 
import com.scalar.database.exception.transaction.CommitException; 
import com.scalar.database.exception.transaction.CrudException; 
import com.scalar.database.exception.transaction.UnknownTransactionStatusException; 
import java.util.Optional;

import com.scalar.database.api.Scan; 
import com.scalar.database.api.Scanner;

public class ElectronicMoney {
  //Klassenvariablen definieren
  private final String NAMESPACE = "emoney";
  private final String TABLE_NAME = "account";
  private final String ID = "id";
  private final String GROUP_ID = "group_id";
  private final String BALANCE = "balance";
  private final StorageService storageService;
  private final TransactionService transactionService;

  //Konstruktor implementieren
  public ElectronicMoney() throws IOException {
   File prop_file = new File("/etc/scalar/database.properties");
   DatabaseConfig config = new DatabaseConfig(prop_file);
   Injector injector = Guice.createInjector(new StorageModule(config));
   storageService = injector.getInstance(StorageService.class);
   storageService.with(NAMESPACE, TABLE_NAME);
   injector = Guice.createInjector(new TransactionModule(config));
   transactionService = injector.getInstance(TransactionService.class);
   transactionService.with(NAMESPACE, TABLE_NAME);
  }

  public void charge(String groupId, String id, int amount) throws CrudException, CommitException, UnknownTransact ionStatusException {
   //Transaktionsstart
   DistributedTransaction tx = transactionService.start();
   Key partitionKey = new Key(new TextValue(GROUP_ID, groupId));
   Key clusteringKey = new Key(new TextValue(ID, id));
   Get get = new Get(partitionKey, clusteringKey);
   Optional<Result> result = tx.get(get);
   int balance = amount;

   if (result.isPresent()) {
    int current = ((IntValue) result.get().getValue(BALANCE).get()).get();
    balance += current;
   }

   //Guthaben aktualisieren
   Put put = new Put(partitionKey, clusteringKey).withValue(new IntValue(BALANCE, balance));
   tx.put(put);
   //Transaktions-Commit
   tx.commit();
  }

  public void pay(String groupId, String fromId, String toId, int amount) throws CrudException,   CommitException, UnknownTransactionStatusException {
   //Transaktionsstart
   DistributedTransaction tx = transactionService.start();
   //Erhalten Sie Kontoinformationen von Absender und Empfänger
   Key partitionKey = new Key(new TextValue(GROUP_ID, groupId));
   Key fromKey = new Key(new TextValue(ID, fromId));
   Key toKey = new Key(new TextValue(ID, toId));
   Get fromGet = new Get(partitionKey, fromKey);
   Get toGet = new Get(partitionKey, toKey);
   Optional<Result> fromResult = tx.get(fromGet);
   Optional<Result> toResult = tx.get(toGet);

   if (!fromResult.isPresent()) {
    throw new RuntimeException(fromId + " doesn't exist.");
   }
   if (!toResult.isPresent()) {
    throw new RuntimeException(toId + " doesn't exist.");
   }
   int newFromBalance = ((IntValue) (fromResult.get().getValue(BALANCE).get())).get() - amount;
   int newToBalance = ((IntValue) (toResult.get().getValue(BALANCE).get())).get() + amount;
   if (newFromBalance < 0) {
    throw new RuntimeException(fromId + " doesn't have enough balances.");
   }
 
   //Guthaben aktualisieren
   Put fromPut = new Put(partitionKey, fromKey).withValue(new IntValue(BALANCE, newFromBalance));
   Put toPut = new Put(partitionKey, toKey).withValue(new IntValue(BALANCE, newToBalance));
   tx.put(fromPut);   tx.put(toPut);
   //Transaktions-Commit
   tx.commit();
  }

  public void balances(String groupId) throws ExecutionException {
   Key partitionKey = new Key(new TextValue(GROUP_ID, groupId));
   Scan scan = new Scan(partitionKey);
   Scanner scanner = storageService.scan(scan);
   scanner.forEach(r -> {
    r.getValue(ID).ifPresent(v -> System.out.print(((TextValue) v).getString().get()));
    System.out.print(" : ");
    r.getValue(BALANCE).ifPresent(v -> System.out.println(((IntValue) v).get()));
   });
  }

  public void deleteUser(String groupId, String id) throws CrudException, CommitException, UnknownTransactionStatu sException {
   //Transaktionsstart
   DistributedTransaction tx = transactionService.start();
   Key partitionKey = new Key(new TextValue(GROUP_ID, groupId));
   Key clusteringKey = new Key(new TextValue(ID, id));
   Get get = new Get(partitionKey, clusteringKey);
   Optional<Result> result = tx.get(get);
   if (!result.isPresent()) {
    tx.abort();
    return;
   }

    //Guthaben aktualisieren
   Delete delete = new Delete(partitionKey, clusteringKey);
   tx.delete(delete);
   //Transaktions-Commit
   tx.commit();
  }

  public void close() {
   storageService.close();
   transactionService.close();
  }
}

$ vi ElectronicMoneyMain.java

ElectronicMoneyMain.java


package sample.emoney; 

public class ElectronicMoneyMain {
 public static void main(String[] args) throws Exception {
  String action = null;
  int amount = 0;
  String group = null;
  String to = null;
  String from = null;

  for (int i = 0; i < args.length; ++i) {
   if ("-action".equals(args[i])) {
    action = args[++i];
   } else if ("-group".equals(args[i])) {
    group = args[++i];
   } else if ("-amount".equals(args[i])) {
    amount = Integer.parseInt(args[++i]);
   } else if ("-to".equals(args[i])) {
    to = args[++i];
   } else if ("-from".equals(args[i])) {
    from = args[++i];
   } else if ("-help".equals(args[i])) {
    printUsageAndExit();
   }
  }

 ElectronicMoney eMoney = new ElectronicMoney();
 if (action.equalsIgnoreCase("charge")) {
   eMoney.charge(group, to, amount);
  } else if (action.equalsIgnoreCase("pay")) {
   if (from == null) {
   printUsageAndExit();
   }
   eMoney.pay(group, from, to, amount);
  } else if (action.equalsIgnoreCase("balances")) {
   eMoney.balances(group);
  } else if (action.equalsIgnoreCase("delete")) {
   eMoney.deleteUser(group, to);
  }
  eMoney.close();
 }

 private static void printUsageAndExit() {
  System.err.println(
   "ElectronicMoneyMain -action charge/pay/balances/delete -group id -to id [-amount number (needed for charge/pay)] [-from id (needed for pay)]"
  );
  System.exit(1);
 }
}

Lauf

  1. Laden

1000 Gebühr an Benutzer1 $ gradle run --args="-action charge -amount 1000 -group groupA -to user1"

0 Gebühr an Benutzer2 $ gradle run --args="-action charge -amount 0 -group groupA -to user2"

Überprüfen Sie das Gleichgewicht zwischen Benutzer1 und Benutzer2 $ gradle run --args="-action balances -group groupA" image.png

  1. Zahlung

300 Zahlungen von Benutzer1 an Benutzer2 $ gradle run --args="-action pay -amount 300 -group groupA -to user2 -from user1"

Überprüfen Sie das Gleichgewicht zwischen Benutzer1 und Benutzer2 $ gradle run --args="-action balances -group groupA" image.png

  1. Benutzer löschen

Benutzer1 löschen $ gradle run --args="-action delete -group groupA -to user1"

Überprüfen Sie den Kontostand von Benutzer2 und stellen Sie sicher, dass Benutzer1 gelöscht wurde $ gradle run --args="-action balances -group groupA" image.png

  1. Bestätigung der Transaktionsfunktion

Ändern Sie "ElectronicMoney.java", um sicherzustellen, dass die Transaktionsfunktion funktioniert.

$ vi ElectronicMoney.java

ElectronicMoney.java(Bezahlfunktion,In der Nähe der Linie 101)


  public void pay(String groupId, String fromId, String toId, int amount) throws CrudException,   CommitException, UnknownTransactionStatusException {
   //Transaktionsstart
   DistributedTransaction tx = transactionService.start();
   //Erhalten Sie Kontoinformationen von Absender und Empfänger
   Key partitionKey = new Key(new TextValue(GROUP_ID, groupId));
   Key fromKey = new Key(new TextValue(ID, fromId));
   Key toKey = new Key(new TextValue(ID, toId));
   Get fromGet = new Get(partitionKey, fromKey);
   Get toGet = new Get(partitionKey, toKey);
   Optional<Result> fromResult = tx.get(fromGet);
   Optional<Result> toResult = tx.get(toGet);

   if (!fromResult.isPresent()) {
    throw new RuntimeException(fromId + " doesn't exist.");
   }
   if (!toResult.isPresent()) {
    throw new RuntimeException(toId + " doesn't exist.");
   }
   int newFromBalance = ((IntValue) (fromResult.get().getValue(BALANCE).get())).get() - amount;
   int newToBalance = ((IntValue) (toResult.get().getValue(BALANCE).get())).get() + amount;
   if (newFromBalance < 0) {
    throw new RuntimeException(fromId + " doesn't have enough balances.");
   }
 
   //Guthaben aktualisieren
   Put fromPut = new Put(partitionKey, fromKey).withValue(new IntValue(BALANCE, newFromBalance));
   // ----------------Zusätzliche Zeilen von hier-----------------------
   //Fügen Sie eine Anweisung hinzu, die beim Experimentieren immer einen Fehler auslöst
   if (newFromBalance >= 0){
    throw new RuntimeException("test error.");
   }
   // ----------------Zusätzliche Zeilen bis hierher-----------------------
   //Der Kontostand des Empfängers wird nicht aktualisiert
   Put toPut = new Put(partitionKey, toKey).withValue(new IntValue(BALANCE, newToBalance));
   tx.put(fromPut);   tx.put(toPut);
   //Transaktions-Commit
   tx.commit();
  }

1000 Gebühr an Benutzer1 $ gradle run --args="-action charge -amount 1000 -group groupA -to user1"

0 Gebühr an Benutzer2 $ gradle run --args="-action charge -amount 0 -group groupA -to user2"

Überprüfen Sie den Saldo vor der Ausführung gradle run --args="-action balances -group groupA" image.png Versuchen Sie, den Überweisungsprozess auszuführen gradle run --args="-action pay -amount 300 -group groupA -to user2 -from user1"

Das ist alles zum Ausführen der Beispiel-App. Danke fürs Lesen.

Recommended Posts

Versuchen Sie, ScalarDB unter WSL Ubuntu auszuführen (Beispiel-App-Erstellung)
Versuchen Sie, ScalarDB unter WSL Ubuntu (Environment Construction) auszuführen.
Versuchen Sie, Docker in Ubuntu auf WSL zu setzen
Probieren Sie DisplayLink unter Ubuntu 20.04 aus
Installieren Sie Java unter WSL Ubuntu 18.04
Versuchen Sie, Spring Boot auf Kubernetes auszuführen
Elmer / Ice Installation (Ubuntu auf WSL)
Ruby on Rails-Anwendung neuer Erstellungsbefehl
Verwenden Sie cljstyle mit Spacemacs unter Ubuntu unter WSL2
Richten Sie unter Ubuntu 20.04 einen SSH-Server ein, nämlich WSL2
Installationsanweisungen für Docker unter Ubuntu18.04 unter WSL2 und VSCode