Beispiel für eine JDBC-Transaktion
JDBC-Transaktion stellt sicher, dass eine Reihe von SQL-Anweisungen als Einheit ausgeführt wird, entweder alle Anweisungen erfolgreich ausgeführt werden oder KEINE der Anweisungen ausgeführt wird (alle Änderungen rückgängig gemacht).
1. Ohne JDBC-Transaktion
1.1 A JDBC example to insert two rows and update one row.
TransactionExample.java
package com.example.jdbc;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDateTime;
public class TransactionExample {
public static void main(String[] args) {
try (Connection conn = DriverManager.getConnection(
"jdbc:postgresql://127.0.0.1:5432/test", "postgres", "password");
Statement statement = conn.createStatement();
PreparedStatement psInsert = conn.prepareStatement(SQL_INSERT);
PreparedStatement psUpdate = conn.prepareStatement(SQL_UPDATE)) {
statement.execute(SQL_TABLE_DROP);
statement.execute(SQL_TABLE_CREATE);
// Run list of insert commands
psInsert.setString(1, "example");
psInsert.setBigDecimal(2, new BigDecimal(10));
psInsert.setTimestamp(3, Timestamp.valueOf(LocalDateTime.now()));
psInsert.execute();
psInsert.setString(1, "kungfu");
psInsert.setBigDecimal(2, new BigDecimal(20));
psInsert.setTimestamp(3, Timestamp.valueOf(LocalDateTime.now()));
psInsert.execute();
// Run list of update commands
// below line caused error, test transaction
// org.postgresql.util.PSQLException: No value specified for parameter 1.
psUpdate.setBigDecimal(2, new BigDecimal(999.99));
//psUpdate.setBigDecimal(1, new BigDecimal(999.99));
psUpdate.setString(2, "example");
psUpdate.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
private static final String SQL_INSERT = "INSERT INTO EMPLOYEE (NAME, SALARY, CREATED_DATE) VALUES (?,?,?)";
private static final String SQL_UPDATE = "UPDATE EMPLOYEE SET SALARY=? WHERE NAME=?";
private static final String SQL_TABLE_CREATE = "CREATE TABLE EMPLOYEE"
+ "("
+ " ID serial,"
+ " NAME varchar(100) NOT NULL,"
+ " SALARY numeric(15, 2) NOT NULL,"
+ " CREATED_DATE timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,"
+ " PRIMARY KEY (ID)"
+ ")";
private static final String SQL_TABLE_DROP = "DROP TABLE EMPLOYEE";
}
Ausgabe, das Update ist fehlgeschlagen und eine Ausnahme wird ausgelöst. Am Ende werden 2 Zeilen eingefügt, aber das Update wird übersprungen.
org.postgresql.util.PSQLException: No value specified for parameter 1.
at org.postgresql.core.v3.SimpleParameterList.checkAllParametersSet(SimpleParameterList.java:257)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:292)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:143)
at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:132)
at com.example.jdbc.TransactionExample.main(TransactionExample.java:41)

2. Verwenden der JDBC-Transaktion
2.1 To enable transaction, set auto commit to false.
conn.setAutoCommit(false); // default true // start transaction block // insert // update // if any errors within the start and end block, // rolled back all changes, none of the statements are executed. // end transaction block conn.commit();
2.2 Same example with JDBC transaction.
TransactionExample.java
package com.example.jdbc;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDateTime;
public class TransactionExample {
public static void main(String[] args) {
try (Connection conn = DriverManager.getConnection(
"jdbc:postgresql://127.0.0.1:5432/test", "postgres", "password");
Statement statement = conn.createStatement();
PreparedStatement psInsert = conn.prepareStatement(SQL_INSERT);
PreparedStatement psUpdate = conn.prepareStatement(SQL_UPDATE)) {
statement.execute(SQL_TABLE_DROP);
statement.execute(SQL_TABLE_CREATE);
// start transaction block
conn.setAutoCommit(false); // default true
// Run list of insert commands
psInsert.setString(1, "example");
psInsert.setBigDecimal(2, new BigDecimal(10));
psInsert.setTimestamp(3, Timestamp.valueOf(LocalDateTime.now()));
psInsert.execute();
psInsert.setString(1, "kungfu");
psInsert.setBigDecimal(2, new BigDecimal(20));
psInsert.setTimestamp(3, Timestamp.valueOf(LocalDateTime.now()));
psInsert.execute();
// Run list of update commands
// error, test roolback
// org.postgresql.util.PSQLException: No value specified for parameter 1.
psUpdate.setBigDecimal(2, new BigDecimal(999.99));
//psUpdate.setBigDecimal(1, new BigDecimal(999.99));
psUpdate.setString(2, "example");
psUpdate.execute();
// end transaction block, commit changes
conn.commit();
// good practice to set it back to default true
conn.setAutoCommit(true);
} catch (Exception e) {
e.printStackTrace();
}
}
//...
}
Ausgabe, keine der Anweisungen wird ausgeführt, die Einfügeanweisungen werden zurückgesetzt.
org.postgresql.util.PSQLException: No value specified for parameter 1.
at org.postgresql.core.v3.SimpleParameterList.checkAllParametersSet(SimpleParameterList.java:257)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:292)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:143)
at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:132)
at com.example.jdbc.TransactionExample.main(TransactionExample.java:41)

3. Extra…
Beheben Sie den Fehlerparameter 1und sehen Sie das erwartete Ergebnis.
//psUpdate.setBigDecimal(2, new BigDecimal(999.99));
psUpdate.setBigDecimal(1, new BigDecimal(999.99));
psUpdate.setString(2, "example");
psUpdate.execute();
Ausgabe
2 rows are inserted and 1 row is updated.

Quellcode herunterladen
$ git clone https://github.com/example/java-jdbc.git
$ cd postgresql