diff --git a/rdbms/Conn.cpp b/rdbms/Conn.cpp
index f70c14b855d45147253aa655e85826fc8f7cd47e..75462ba85ce3541ed045769df6bcd5a333bbd2e5 100644
--- a/rdbms/Conn.cpp
+++ b/rdbms/Conn.cpp
@@ -67,5 +67,19 @@ void Conn::executeNonQuery(const std::string &sql, const Stmt::AutocommitMode au
   }
 }
 
+//------------------------------------------------------------------------------
+// setHealthy
+//------------------------------------------------------------------------------
+void Conn::setHealthy(const bool value) {
+  m_healthy = value;
+}
+
+//------------------------------------------------------------------------------
+// getHealthy
+//------------------------------------------------------------------------------
+bool Conn::getHealthy() const {
+  return m_healthy;
+}
+
 } // namespace rdbms
 } // namespace cta
diff --git a/rdbms/Conn.hpp b/rdbms/Conn.hpp
index 7a9f08f051e170f5a4ce694ed0a8d35954f1836a..684b97e58cf65ea12cfd54c36a709605683d72fc 100644
--- a/rdbms/Conn.hpp
+++ b/rdbms/Conn.hpp
@@ -20,6 +20,7 @@
 
 #include "Stmt.hpp"
 
+#include <atomic>
 #include <list>
 #include <memory>
 #include <string>
@@ -93,6 +94,29 @@ public:
    */
   virtual std::list<std::string> getTableNames() = 0;
 
+  /**
+   * Returns true if the connection is healthy.
+   *
+   * @return True if the connection is healthy.
+   */
+  bool getHealthy() const;
+
+protected:
+
+  /**
+   * Sets the status of the connection to be either healthy or not healthy.
+   *
+   * @param value True if the connection is healthy.
+   */
+  void setHealthy(const bool value);
+
+private:
+
+  /**
+   * True if the connection's state is healthy.
+   */
+  std::atomic<bool> m_healthy{true};
+
 }; // class Conn
 
 } // namespace rdbms
diff --git a/rdbms/ConnPool.cpp b/rdbms/ConnPool.cpp
index ed75b79df17cbb9bccb250e2eb501e64d850a44f..e9101aa26e179d4169b8bfc6fc32ecab0aad5742 100644
--- a/rdbms/ConnPool.cpp
+++ b/rdbms/ConnPool.cpp
@@ -69,10 +69,24 @@ PooledConn ConnPool::getConn() {
 // returnConn
 //------------------------------------------------------------------------------
 void ConnPool::returnConn(Conn *const conn) {
-  conn->commit();
-  std::unique_lock<std::mutex> lock(m_connsMutex);
-  m_conns.emplace_back(conn);
-  m_connsCv.notify_one();
+  // If the connection is healthy
+  if(conn->getHealthy()) {
+
+    // Commit the connection and put it back in the pool
+    conn->commit();
+    std::unique_lock<std::mutex> lock(m_connsMutex);
+    m_conns.emplace_back(conn);
+    m_connsCv.notify_one();
+
+  // Else the connection is not healthy
+  } else {
+
+    // Close the connection and put a brand new one in the pool
+    delete conn;
+    std::unique_lock<std::mutex> lock(m_connsMutex);
+    m_conns.push_back(m_connFactory.create());
+    m_connsCv.notify_one();
+  }
 }
 
 } // namespace rdbms
diff --git a/rdbms/ConnPool.hpp b/rdbms/ConnPool.hpp
index 7cf1c0c020787de63a0a7fa356411a6c9d508bad..c3fa7ce85344db60888b35bc0ee92ced0c0852be 100644
--- a/rdbms/ConnPool.hpp
+++ b/rdbms/ConnPool.hpp
@@ -60,8 +60,11 @@ private:
   friend PooledConn;
 
   /**
-   * Calls commit on the specified database connection and returns it to the
-   * pool.
+   * If the specified database connection is healthy, then this method calls
+   * commit on the connection and returns it to the pool.
+   *
+   * If the specified database connection is no healthy, then this method
+   * closes the connection and creates a new one in the connection pool.
    *
    * @param conn The connection to be commited and returned to the pool.
    */
diff --git a/rdbms/OcciConn.cpp b/rdbms/OcciConn.cpp
index a379fab4a4672947349bec0eac3732b4c3811958..9b8cd0a8044cbc842bdef9ac6c88abc37e693338 100644
--- a/rdbms/OcciConn.cpp
+++ b/rdbms/OcciConn.cpp
@@ -138,5 +138,40 @@ std::list<std::string> OcciConn::getTableNames() {
   }
 }
 
+//------------------------------------------------------------------------------
+// updateHealth
+//------------------------------------------------------------------------------
+void OcciConn::updateHealth(const oracle::occi::SQLException &ex) {
+  using namespace oracle;
+
+  // Error codes that identify an unhealthy connection
+  // The majority of these error codes were learnt from CASTOR
+  switch(ex.getErrorCode()) {
+  case    28:
+  case  1003:
+  case  1008:
+  case  1012:
+  case  1033:
+  case  1089:
+  case  2392:
+  case  2399:
+  case  3113:
+  case  3114:
+  case  3135:
+  case 12170:
+  case 12541:
+  case 12571:
+  case 24338:
+  case 12537:
+  case 25401:
+  case 25409:
+  case 32102:
+    setHealthy(false);
+    break;
+  default:
+    break;
+  };
+}
+
 } // namespace rdbms
 } // namespace cta
diff --git a/rdbms/OcciConn.hpp b/rdbms/OcciConn.hpp
index d922bf7ce236b46a6d29e758318e765406de8460..59c01ee0faf6c2d43a0ec24e4d59d74e0b2b5b4c 100644
--- a/rdbms/OcciConn.hpp
+++ b/rdbms/OcciConn.hpp
@@ -105,6 +105,8 @@ public:
 
 private:
 
+  friend OcciStmt;
+
   /**
    * Mutex used to serialize access to this object.
    */
@@ -120,6 +122,14 @@ private:
    */
   oracle::occi::Connection *m_conn;
 
+  /**
+   * Determines whether or not the specified Oracle exception affects the status
+   * of the database connection and updates it accordingly.
+   *
+   * @param ex The Oracle exception.
+   */
+  void updateHealth(const oracle::occi::SQLException &ex);
+
 }; // class OcciConn
 
 } // namespace rdbms
diff --git a/rdbms/OcciStmt.cpp b/rdbms/OcciStmt.cpp
index af81221ba2c21d8d97aa2fc9002e665dec9e5561..2aaf5583aa11fa82b03c761e27d78a239fdfd6e6 100644
--- a/rdbms/OcciStmt.cpp
+++ b/rdbms/OcciStmt.cpp
@@ -23,7 +23,6 @@
 #include "rdbms/OcciStmt.hpp"
 
 #include <cstring>
-#include <iostream>
 #include <map>
 #include <sstream>
 #include <stdexcept>
@@ -181,11 +180,9 @@ std::unique_ptr<Rset> OcciStmt::executeQuery() {
 
   try {
     return cta::make_unique<OcciRset>(*this, m_stmt->executeQuery());
-  } catch(exception::Exception &ex) {
-    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + getSql() + ": " +
-      ex.getMessage().str());
-  } catch(std::exception &se) {
-    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + getSql() + ": " + se.what());
+  } catch(occi::SQLException &ex) {
+    m_conn.updateHealth(ex);
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + getSql() + ": " + ex.what());
   }
 }
 
@@ -197,11 +194,9 @@ void OcciStmt::executeNonQuery() {
 
   try {
     m_stmt->executeUpdate();
-  } catch(exception::Exception &ex) {
-    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + getSql() + ": " +
-      ex.getMessage().str());
-  } catch(std::exception &se) {
-    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + getSql() + ": " + se.what());
+  } catch(occi::SQLException &ex) {
+    m_conn.updateHealth(ex);
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + getSql() + ": " + ex.what());
   }
 }