diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9a9e05bfc25bd5ac02a29b3c02991d78e81fc995..a7d3fd6167a5761740dcf3af45acd04b249c77a8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.16)
 
 project(
   kea-hook
-  VERSION 3.0
+  VERSION 3.0.0
   DESCRIPTION
     "Hook library for isc kea(https://kea.isc.org/), the library controls IP assignment."
   LANGUAGES CXX)
diff --git a/src/callouts.cc b/src/callouts.cc
index 41beafdbf41d9fc19c8020e992d3a7944aac9f42..5e841675394457629919e5a453e7c2eb774716ac 100644
--- a/src/callouts.cc
+++ b/src/callouts.cc
@@ -36,14 +36,13 @@ static std::tuple<int, std::string, std::string, std::string> parseOption82(
     return std::make_tuple(1, nullptr, nullptr, nullptr);
   }
 
-  std::string port_id{std::to_string(circuit_id[4]) + "/" +
+  const auto& port_id{std::to_string(circuit_id[4]) + "/" +
                       std::to_string(circuit_id[5])};
   std::string switch_name{remote_id.begin() + 2, remote_id.end()};
 
   try {
     const auto& switch_id{g_switch_data.at(switch_name)};
-    return std::make_tuple(0, std::move(switch_name), std::move(port_id),
-                           switch_id);
+    return std::make_tuple(0, std::move(switch_name), port_id, switch_id);
   } catch (const std::out_of_range& e) {
     LOG_FATAL(kea_hook_logger, KEA_HOOK_DHCP_OPTION_82_ERROR);
     return std::make_tuple(1, nullptr, nullptr, nullptr);
@@ -145,82 +144,96 @@ int lease4_select(isc::hooks::CalloutHandle& handle) {
 
   // Critical part begin, it's not safe to lease IP yet
   handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_SKIP);
+  try {
+    isc::db::PgSqlTransaction transaction(*g_pg_sql_connection);
 
-  auto [result, switch_name, port_id, switch_id] = parseOption82(query4_ptr);
-  if (result != 0) {
-    return 1;
-  }
+    auto [result, switch_name, port_id, switch_id] = parseOption82(query4_ptr);
+    if (result != 0) {
+      return 1;
+    }
 
-  // Check for IP override
-  const char* values[3] = {mac_address.c_str()};
-  isc::db::PgSqlResult r(PQexecPrepared(*g_pg_sql_connection, "ip_override", 1,
-                                        values, nullptr, nullptr, 0));
+    // Check for IP override
+    const char* values[3] = {mac_address.c_str()};
+    isc::db::PgSqlResult r(PQexecPrepared(*g_pg_sql_connection, "ip_override",
+                                          1, values, nullptr, nullptr, 0));
 
-  std::string ip_address;
-  if (r.getRows() > 0) {
-    // IP is overridden
-    ip_address = PQgetvalue(r, 0, 0);
-    LOG_INFO(kea_hook_logger, KEA_HOOK_IP_OVERRIDDEN)
-        .arg(mac_address)
-        .arg(ip_address);
-  } else {
-    values[0] = port_id.c_str();
-    values[1] = switch_id.c_str();
-    isc::db::PgSqlResult r2(PQexecPrepared(*g_pg_sql_connection, "ip_address",
-                                           2, values, nullptr, nullptr, 0));
-
-    // Handle incorrect room
-    if (r2.getRows() <= 0) {
-      LOG_ERROR(kea_hook_logger, KEA_HOOK_UNKNOWN_ROOM)
+    std::string ip_address;
+    if (r.getRows() > 0) {
+      // IP is overridden
+      ip_address = PQgetvalue(r, 0, 0);
+      LOG_INFO(kea_hook_logger, KEA_HOOK_IP_OVERRIDDEN)
           .arg(mac_address)
-          .arg(switch_name)
-          .arg(port_id);
-
-      return 1;
+          .arg(ip_address);
+    } else {
+      values[0] = port_id.c_str();
+      values[1] = switch_id.c_str();
+      isc::db::PgSqlResult r2(PQexecPrepared(*g_pg_sql_connection, "ip_address",
+                                             2, values, nullptr, nullptr, 0));
+
+      // Handle incorrect room
+      if (r2.getRows() <= 0) {
+        LOG_ERROR(kea_hook_logger, KEA_HOOK_UNKNOWN_ROOM)
+            .arg(mac_address)
+            .arg(switch_name)
+            .arg(port_id);
+
+        return 1;
+      }
+
+      ip_address = PQgetvalue(r2, 0, 0);
     }
 
-    ip_address = PQgetvalue(r2, 0, 0);
-  }
+    // Modify kea's IP lease
+    lease4_ptr->addr_ = isc::asiolink::IOAddress(ip_address);
+    handle.setArgument("lease4", lease4_ptr);
 
-  // Modify kea's IP lease
-  lease4_ptr->addr_ = isc::asiolink::IOAddress(ip_address);
-  handle.setArgument("lease4", lease4_ptr);
+    // Basic DHCP functionality ends here
+    // Critical part end, it's safe to lease IP now
+    handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_CONTINUE);
 
-  // Basic DHCP functionality ends here
-  // Critical part end, it's safe to lease IP now
-  handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_CONTINUE);
+    LOG_DEBUG(kea_hook_logger, 0, KEA_HOOK_QUERIED_IP).arg(ip_address);
+    LOG_DEBUG(kea_hook_logger, 0, KEA_HOOK_DHCP_STATE)
+        .arg((fake_allocation) ? "---<DISCOVER>---" : "---<REQUEST>---");
 
-  LOG_DEBUG(kea_hook_logger, 0, KEA_HOOK_QUERIED_IP).arg(ip_address);
-  LOG_DEBUG(kea_hook_logger, 0, KEA_HOOK_DHCP_STATE)
-      .arg((fake_allocation) ? "---<DISCOVER>---" : "---<REQUEST>---");
-
-  // Save to DB when the DHCP state is DHCPREQUEST
-  if (!fake_allocation) {
-    // Clear switch-port
-    values[0] = port_id.c_str();
-    values[1] = switch_id.c_str();
-    isc::db::PgSqlResult r3(PQexecPrepared(*g_pg_sql_connection, "clear_port",
-                                           2, values, nullptr, nullptr, 0));
-
-    // Insert MUEB or update switch-port
-    values[0] = mac_address.c_str();
-    values[1] = port_id.c_str();
-    values[2] = switch_id.c_str();
-    isc::db::PgSqlResult r4(PQexecPrepared(*g_pg_sql_connection,
-                                           "insert_or_mueb", 3, values, nullptr,
-                                           nullptr, 0));
-  } else {
-    /* Handle device swap
-     * Remove the current IP from the lease DB before DHCPREQUEST
-     * This step is required to make the device swap work otherwise the server
-     * sends DHCPNAK
-     */
-    if (isc::dhcp::LeaseMgrFactory::haveInstance()) {
-      isc::dhcp::LeaseMgrFactory::instance().deleteLease(lease4_ptr);
+    // Save to DB when the DHCP state is DHCPREQUEST
+    if (!fake_allocation) {
+      // Clear switch-port
+      isc::db::PgSqlResult r3(PQexecPrepared(*g_pg_sql_connection, "clear_port",
+                                             2, values, nullptr, nullptr, 0));
+
+      // Insert MUEB or update switch-port
+      values[0] = mac_address.c_str();
+      values[1] = port_id.c_str();
+      values[2] = switch_id.c_str();
+      isc::db::PgSqlResult r4(PQexecPrepared(*g_pg_sql_connection,
+                                             "insert_or_update_mueb", 3, values,
+                                             nullptr, nullptr, 0));
+    } else {
+      /* Handle device swap
+       * Remove the current IP from the lease DB before DHCPREQUEST
+       * This step is required to make the device swap work otherwise the server
+       * sends DHCPNAK
+       */
+      if (isc::dhcp::LeaseMgrFactory::haveInstance()) {
+        isc::dhcp::LeaseMgrFactory::instance().deleteLease(lease4_ptr);
+      } else {
+        /* Should not happen this needs manual fix
+         * Proceed as normal
+         */
+        LOG_ERROR(kea_hook_logger, KEA_HOOK_FAILED)
+            .arg(
+                "No lease manager available, MUEB device swap will not work! "
+                "This should not happen, check lease database configuration!");
+      }
     }
-  }
 
-  return 0;
+    transaction.commit();
+    return 0;
+  } catch (const std::exception& e) {
+    LOG_FATAL(kea_hook_logger, KEA_HOOK_FAILED).arg(e.what());
+
+    return 1;
+  }
 }
 
 /* Handle lease after one allocation
diff --git a/src/framework_functions.cc b/src/framework_functions.cc
index 0146100859bbea04f90a288ea9b1ac2653ce86d8..2e74f6b04a277284cd1817233d77b28e1a30cd7d 100644
--- a/src/framework_functions.cc
+++ b/src/framework_functions.cc
@@ -39,11 +39,7 @@ int load(isc::hooks::LibraryHandle& handle) {
 
     // Store prepared statements
     std::array<isc::db::PgSqlTaggedStatement, 8> statements{
-        {{1,
-          {829},
-          "ip_conflict",
-          "select ip_conflict::int from mueb where mac_address = $1"},
-         {2,
+        {{2,
           {isc::db::OID_TEXT, 869},
           "mueb_in_room",
           "select room_id from port p join room r using(room_id) where "
@@ -54,6 +50,10 @@ int load(isc::hooks::LibraryHandle& handle) {
           "mueb_count_in_room",
           "select count(*) from port p join mueb m using(port_id, switch_id) "
           "where m.mac_address != $1 and p.room_id = $2"},
+         {1,
+          {829},
+          "ip_conflict",
+          "select ip_conflict::int from mueb where mac_address = $1"},
          {1,
           {829},
           "ip_override",
diff --git a/src/messages.cc b/src/messages.cc
index a40b881d452d4a8e8177beb548562d62a29e0fa5..77322365ed87aaf3bd5479200355bc44a0289fbf 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -1,4 +1,4 @@
-// File created from messages.mes on Fri Sep 03 2021 19:53
+// File created from messages.mes on Sat Sep 04 2021 16:53
 
 #include <cstddef>
 #include <log/message_types.h>
@@ -7,6 +7,7 @@
 extern const isc::log::MessageID KEA_HOOK_DATABASE_FAILED = "KEA_HOOK_DATABASE_FAILED";
 extern const isc::log::MessageID KEA_HOOK_DHCP_OPTION_82_ERROR = "KEA_HOOK_DHCP_OPTION_82_ERROR";
 extern const isc::log::MessageID KEA_HOOK_DHCP_STATE = "KEA_HOOK_DHCP_STATE";
+extern const isc::log::MessageID KEA_HOOK_FAILED = "KEA_HOOK_FAILED";
 extern const isc::log::MessageID KEA_HOOK_IP_CONFLICT = "KEA_HOOK_IP_CONFLICT";
 extern const isc::log::MessageID KEA_HOOK_IP_OVERRIDDEN = "KEA_HOOK_IP_OVERRIDDEN";
 extern const isc::log::MessageID KEA_HOOK_MISSING_PARAMETERS = "KEA_HOOK_MISSING_PARAMETERS";
@@ -22,6 +23,7 @@ const char* values[] = {
     "KEA_HOOK_DATABASE_FAILED", "%1",
     "KEA_HOOK_DHCP_OPTION_82_ERROR", "Invalid DHCP option 82",
     "KEA_HOOK_DHCP_STATE", "%1",
+    "KEA_HOOK_FAILED", "%1",
     "KEA_HOOK_IP_CONFLICT", "Could not lease IP: %1 to MUEB: %2 because of IP conflict",
     "KEA_HOOK_IP_OVERRIDDEN", "MUEB: %1 IP's overridden to: %2",
     "KEA_HOOK_MISSING_PARAMETERS", "Not all parameters are provided",
diff --git a/src/messages.h b/src/messages.h
index 2b417c513eb25f65c590e90b113d8d6006a06995..71609e4d1d70e5962b5b2df6ae5d818a2d9a27a0 100644
--- a/src/messages.h
+++ b/src/messages.h
@@ -1,4 +1,4 @@
-// File created from messages.mes on Fri Sep 03 2021 19:53
+// File created from messages.mes on Sat Sep 04 2021 16:53
 
 #ifndef MESSAGES_H
 #define MESSAGES_H
@@ -8,6 +8,7 @@
 extern const isc::log::MessageID KEA_HOOK_DATABASE_FAILED;
 extern const isc::log::MessageID KEA_HOOK_DHCP_OPTION_82_ERROR;
 extern const isc::log::MessageID KEA_HOOK_DHCP_STATE;
+extern const isc::log::MessageID KEA_HOOK_FAILED;
 extern const isc::log::MessageID KEA_HOOK_IP_CONFLICT;
 extern const isc::log::MessageID KEA_HOOK_IP_OVERRIDDEN;
 extern const isc::log::MessageID KEA_HOOK_MISSING_PARAMETERS;
diff --git a/src/messages.mes b/src/messages.mes
index b5b30127e919152a7f12c7da28dd89781d0399ab..934344cf1ee2239491e88c64b26b7da0a3fd9ce3 100644
--- a/src/messages.mes
+++ b/src/messages.mes
@@ -2,6 +2,8 @@
 
 % KEA_HOOK_OPEN_DATABASE Opened database successfully
 
+% KEA_HOOK_FAILED %1
+
 % KEA_HOOK_DATABASE_FAILED %1
 
 % KEA_HOOK_QUERIED_IP Queried IP is: %1