From 810099b8c594d80fb7803642cd7640e896179dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rg=20Prante?= Date: Fri, 3 Jun 2022 18:59:26 +0200 Subject: [PATCH] remove close() from database provider commit and rollback in transact --- .../org/xbib/jdbc/query/DatabaseProvider.java | 97 ++++++++++++++++++- .../org/xbib/jdbc/query/test/DerbyTest.java | 3 +- 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/DatabaseProvider.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/DatabaseProvider.java index 409c416..28d0f02 100644 --- a/jdbc-query/src/main/java/org/xbib/jdbc/query/DatabaseProvider.java +++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/DatabaseProvider.java @@ -56,7 +56,6 @@ public final class DatabaseProvider implements Supplier { /** * Configure the database from the following properties read from the provided configuration: - *
*
      *   database.url=...       Database connect string (required)
      *   database.user=...      Authenticate as this user (optional if provided in url)
@@ -659,6 +658,24 @@ public final class DatabaseProvider implements Supplier {
     }
 
     public void transact(final DbCode code) {
+        boolean complete = false;
+        try {
+            code.run(this);
+            complete = true;
+        } catch (ThreadDeath | DatabaseException t) {
+            throw t;
+        } catch (Throwable t) {
+            throw new DatabaseException("Error during transaction", t);
+        } finally {
+            if (!complete) {
+                rollback();
+            } else {
+                commit();
+            }
+        }
+    }
+
+    public void transactAndClose(final DbCode code) {
         boolean complete = false;
         try {
             code.run(this);
@@ -677,6 +694,26 @@ public final class DatabaseProvider implements Supplier {
     }
 
     public  T transactReturning(final DbCodeTyped code) {
+        T result;
+        boolean complete = false;
+        try {
+            result = code.run(this);
+            complete = true;
+        } catch (ThreadDeath | DatabaseException t) {
+            throw t;
+        } catch (Throwable t) {
+            throw new DatabaseException("Error during transaction", t);
+        } finally {
+            if (!complete) {
+                rollback();
+            } else {
+                commit();
+            }
+        }
+        return result;
+    }
+
+    public  T transactReturningAndClose(final DbCodeTyped code) {
         T result;
         boolean complete = false;
         try {
@@ -697,6 +734,27 @@ public final class DatabaseProvider implements Supplier {
     }
 
     public void transact(final DbCodeTx code) {
+        Transaction tx = new TransactionImpl();
+        tx.setRollbackOnError(true);
+        tx.setRollbackOnly(false);
+        boolean complete = false;
+        try {
+            code.run(this, tx);
+            complete = true;
+        } catch (ThreadDeath | DatabaseException t) {
+            throw t;
+        } catch (Throwable t) {
+            throw new DatabaseException("Error during transaction", t);
+        } finally {
+            if ((!complete && tx.isRollbackOnError()) || tx.isRollbackOnly()) {
+                rollback();
+            } else {
+                commit();
+            }
+        }
+    }
+
+    public void transactAndClose(final DbCodeTx code) {
         Transaction tx = new TransactionImpl();
         tx.setRollbackOnError(true);
         tx.setRollbackOnly(false);
@@ -721,15 +779,12 @@ public final class DatabaseProvider implements Supplier {
         if (delegateTo != null) {
             return delegateTo.get();
         }
-
         if (database != null) {
             return database;
         }
-
         if (connectionProvider == null) {
             throw new DatabaseException("Called get() on a DatabaseProvider after close()");
         }
-
         Metric metric = new Metric(log.isLoggable(Level.FINE));
         try {
             connection = connectionProvider.get();
@@ -824,12 +879,27 @@ public final class DatabaseProvider implements Supplier {
         };
     }
 
+    public void commit() {
+        if (delegateTo != null) {
+            log.fine("Ignoring commit() because this is a fake provider");
+            return;
+        }
+        if (connection != null) {
+            try {
+                if (!options.flavor().autoCommitOnly()) {
+                    connection.commit();
+                }
+            } catch (Exception e) {
+                throw new DatabaseException("Unable to commit the transaction", e);
+            }
+        }
+    }
+
     public void commitAndClose() {
         if (delegateTo != null) {
             log.fine("Ignoring commitAndClose() because this is a fake provider");
             return;
         }
-
         if (connection != null) {
             try {
                 if (!options.flavor().autoCommitOnly()) {
@@ -842,6 +912,23 @@ public final class DatabaseProvider implements Supplier {
         }
     }
 
+    public void rollback() {
+        if (delegateTo != null) {
+            log.fine("Ignoring rollback() because this is a fake provider");
+            return;
+        }
+
+        if (connection != null) {
+            try {
+                if (!options.flavor().autoCommitOnly()) {
+                    connection.rollback();
+                }
+            } catch (Exception e) {
+                log.log(Level.SEVERE, "Unable to rollback the transaction", e);
+            }
+        }
+    }
+
     public void rollbackAndClose() {
         if (delegateTo != null) {
             log.fine("Ignoring rollbackAndClose() because this is a fake provider");
diff --git a/jdbc-query/src/test/java/org/xbib/jdbc/query/test/DerbyTest.java b/jdbc-query/src/test/java/org/xbib/jdbc/query/test/DerbyTest.java
index d16d542..4aab5a1 100644
--- a/jdbc-query/src/test/java/org/xbib/jdbc/query/test/DerbyTest.java
+++ b/jdbc-query/src/test/java/org/xbib/jdbc/query/test/DerbyTest.java
@@ -1,5 +1,6 @@
 package org.xbib.jdbc.query.test;
 
+import java.util.logging.Level;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.xbib.jdbc.query.DatabaseProvider;
@@ -114,7 +115,7 @@ public class DerbyTest extends CommonTest {
         new Schema().addTable("dbtest").addColumn("i").asBigDecimal(31, 31).schema().execute(db);
         BigDecimal value = new BigDecimal("0.9999999999999999999999999999999"); // 31 digits
         db.toInsert("insert into dbtest (i) values (?)").argBigDecimal(value).insert(1);
-        System.out.println(db.toSelect("select i from dbtest").queryBigDecimalOrNull());
+        logger.log(Level.INFO, db.toSelect("select i from dbtest").queryBigDecimalOrNull().toString());
         assertEquals(value,
                 db.toSelect("select i from dbtest where i=?").argBigDecimal(value).queryBigDecimalOrNull());
     }