diff --git a/CMakeLists.txt b/CMakeLists.txt
index abcbaddbe6cea492b54007b468fdb07958c22b1d..39d15c9c54cf933e04bd2827d8175ff91adee090 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -299,7 +299,7 @@ if(_LINTING)
     else()
         message(STATUS "clang-tidy: ${clang_tidy}")
         set(_CMAKE_CXX_CLANG_TIDY_CHECKS
-            "--checks=*,-fuchsia-*,-llvmlibc-*,-readability-convert-member-functions-to-static,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay,-llvm-else-after-return,-readability-else-after-return,-modernize-use-trailing-return-type")
+            "--checks=*,-fuchsia-*,-llvmlibc-*,-readability-convert-member-functions-to-static,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay,-llvm-else-after-return,-readability-else-after-return,-modernize-use-trailing-return-type,-bugprone-branch-clone")
         set(_CMAKE_C_CLANG_TIDY_CHECKS "${_CMAKE_CXX_CLANG_TIDY_CHECKS}")
         set(_CMAKE_CXX_CLANG_TIDY "${clang_tidy}"
             "--header-filter=caosdb/.*[^\(\.pb\.h\)]$"
diff --git a/include/caosdb/status_code.h b/include/caosdb/status_code.h
index 6e5f7587ea0e114e4eab61c4bd3960f80cdb514d..a6fcda905284ae9dfa9b7e46c6be8da36bb32272 100644
--- a/include/caosdb/status_code.h
+++ b/include/caosdb/status_code.h
@@ -24,6 +24,8 @@
 
 #include <string>
 
+namespace caosdb {
+
 /**
  * StatusCodes represent the status of this client, it's connections,
  * configuration and so on.
@@ -33,9 +35,6 @@
  * GENERIC_TRANSACTION_ERROR indicates that *there are* errors in a
  * transaction).
  */
-
-namespace caosdb {
-
 enum StatusCode {
   READY = -4,
   GO_ON = -3,
diff --git a/include/caosdb/transaction.h b/include/caosdb/transaction.h
index 98148d6171306b2d35414934368568faf5bc2962..f9b6a591bb250c37e069c7ce164248aaa14e40e7 100644
--- a/include/caosdb/transaction.h
+++ b/include/caosdb/transaction.h
@@ -18,12 +18,8 @@
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
  *
  */
-
 #ifndef CAOSDB_TRANSACTION_H
 #define CAOSDB_TRANSACTION_H
-/**
- * @brief Creation and execution of transactions.
- */
 #include "boost/log/core/record.hpp"                  // for record
 #include "boost/log/sources/record_ostream.hpp"       // for basic_record_o...
 #include "boost/preprocessor/seq/limits/enum_256.hpp" // for BOOST_PP_SEQ_E...
@@ -37,11 +33,19 @@
 #include "google/protobuf/util/json_util.h" // for MessageToJsonString, Jso...
 #include <stdexcept>
 #include <iterator>
+// IWYU pragma: no_include <ext/alloc_traits.h>
 #include <memory> // for shared_ptr, unique_ptr
 #include <string> // for string
 #include <vector> // for vector
 
-/*
+/**
+ * @brief Creation and execution of transactions.
+ * @author Timm Fitschen
+ * @date 2021-08-05
+ */
+namespace caosdb::transaction {
+
+/**
  * Do all necessary checks and assure that another retrieval (by id or by
  * query) can be added as a sub-request to a transaction.
  */
@@ -62,7 +66,7 @@
       "wrong TransactionType.")                                                \
   }
 
-/*
+/**
  * Do all necessary checks and assure that another deletion can be added as a
  * sub-request to a transaction.
  */
@@ -84,7 +88,7 @@
       "wrong TransactionType.")                                                \
   }
 
-/*
+/**
  * Do all necessary checks and assure that another insertion can be added as a
  * sub-request to a transaction.
  */
@@ -146,8 +150,13 @@ using caosdb::transaction::TransactionStatus;
 using WrappedResponseCase =
   caosdb::entity::v1alpha1::TransactionResponse::WrappedResponseCase;
 
+class Transaction;
+
 static const std::string logger_name = "caosdb::transaction";
 
+/**
+ * Abstract base class for the results of a Transaction.
+ */
 class ResultSet {
 public:
   virtual ~ResultSet() = default;
@@ -155,34 +164,16 @@ public:
   [[nodiscard]] virtual auto At(const int index) const -> const Entity & = 0;
 };
 
+/**
+ * Container with results of a transaction.
+ *
+ * In contrast to UniqueResult, this one can also hold multiple entities or zero
+ * entities.
+ */
 class MultiResultSet : public ResultSet {
 public:
   ~MultiResultSet() = default;
-  explicit inline MultiResultSet(MultiTransactionResponse *response) {
-    auto responses = response->mutable_responses();
-    Entity *entity = nullptr;
-    for (auto sub_response : *responses) {
-      switch (sub_response.wrapped_response_case()) {
-      case WrappedResponseCase::kRetrieveResponse:
-        entity = new Entity(
-          sub_response.mutable_retrieve_response()->release_entity());
-        break;
-      case WrappedResponseCase::kInsertResponse:
-
-        entity = new Entity(sub_response.release_insert_response());
-        break;
-      case WrappedResponseCase::kDeleteResponse:
-        entity = new Entity(sub_response.release_delete_response());
-        break;
-      default:
-        // TODO(tf) Updates
-        break;
-      }
-      if (entity) {
-        this->entities.push_back(std::unique_ptr<Entity>(entity));
-      }
-    }
-  }
+  explicit MultiResultSet(MultiTransactionResponse *response);
   [[nodiscard]] inline auto Size() const noexcept -> int override {
     return this->entities.size();
   }
@@ -193,6 +184,12 @@ public:
   std::vector<std::unique_ptr<Entity>> entities;
 };
 
+/**
+ * Container with the single result of a transaction.
+ *
+ * In contrast to MultiResultSet, this one guarantees to hold exactly one
+ * entity.
+ */
 class UniqueResult : public ResultSet {
 public:
   ~UniqueResult() = default;
@@ -219,14 +216,21 @@ private:
  */
 class Transaction {
 public:
+  /**
+   * The transaction type restricts the kind of sub-transaction which may be
+   * added to a transaction (insertion, update, deletion, retrieval).
+   *
+   * @note MIXED_READ_AND_WRITE and MIXED_WRITE transaction are not supported
+   * yet.
+   */
   enum TransactionType {
-    NONE,
-    READ_ONLY,
-    INSERT,
-    UPDATE,
-    DELETE,
-    MIXED_WRITE,
-    MIXED_READ_AND_WRITE
+    NONE,                /// Unspecified or not specified yet.
+    READ_ONLY,           /// Only retrievals (by id, by query)
+    INSERT,              /// Only insertions
+    UPDATE,              /// Only updates
+    DELETE,              /// Only deletions
+    MIXED_WRITE,         /// Only insertions, deletions, updates
+    MIXED_READ_AND_WRITE /// all kind of transaction.
   };
   Transaction(std::shared_ptr<EntityTransactionService::Stub> service_stub);
 
diff --git a/include/caosdb/transaction_status.h b/include/caosdb/transaction_status.h
index 8e54c8ba79c944f6b157a577cc9db64be01e1473..56c6b005112fd15c76f3c2741803a58837baed9e 100644
--- a/include/caosdb/transaction_status.h
+++ b/include/caosdb/transaction_status.h
@@ -22,15 +22,6 @@
 #ifndef CAOSDB_TRANSACTION_STATUS_H
 #define CAOSDB_TRANSACTION_STATUS_H
 
-/**
- * TransactionStatus indicates the current status of a transaction and, when it
- * has already terminated, whether the transaction has been successful or not.
- *
- * A status code of 0 denotes a generic success state, positive values indicate
- * errors, and negative values indicate other states, such as different stages
- * of a transaction in process.
- */
-
 #include "caosdb/status_code.h"
 #include "caosdb/exceptions.h"
 #include <memory> // for shared_ptr, unique_ptr
@@ -44,7 +35,12 @@ using caosdb::exceptions::Exception;
 using caosdb::exceptions::TransactionError;
 
 /**
- * Status of a Request or Transaction.
+ * TransactionStatus indicates the current status of a transaction and, when it
+ * has already terminated, whether the transaction has been successful or not.
+ *
+ * A status code of 0 denotes a generic success state, positive values indicate
+ * errors, and negative values indicate other states, such as different stages
+ * of a transaction in process.
  */
 class TransactionStatus {
 public:
diff --git a/src/caosdb/configuration.cpp b/src/caosdb/configuration.cpp
index ffa860471821b8733efeadf77801b8155ae6711e..76c437234a48fb339f1e04d71afe3ae84ce94ceb 100644
--- a/src/caosdb/configuration.cpp
+++ b/src/caosdb/configuration.cpp
@@ -39,11 +39,12 @@
 #include <cstdlib>                                     // for getenv
 #include <cstring>                                     // for strcmp
 #include <exception>                                   // IWYU pragma: keep
-#include <grpcpp/security/credentials.h>               // for SslCredentials
-#include <iterator>                                    // for next
-#include <map>                                         // for map
-#include <stdexcept>                                   // for out_of_range
-#include <string>                                      // for string, operator+
+// IWYU pragma: no_include <bits/exception.h>
+#include <grpcpp/security/credentials.h> // for SslCredentials
+#include <iterator>                      // for next
+#include <map>                           // for map
+#include <stdexcept>                     // for out_of_range
+#include <string>                        // for string, operator+
 
 namespace caosdb::configuration {
 using boost::filesystem::exists;
diff --git a/src/caosdb/transaction.cpp b/src/caosdb/transaction.cpp
index ae9ddd2b45c36b272ffcb62c6239a1ccb891bb5c..3e7b4ba7de97a7fa1d5f568451a1414e9189def5 100644
--- a/src/caosdb/transaction.cpp
+++ b/src/caosdb/transaction.cpp
@@ -100,6 +100,29 @@ using grpc::ClientAsyncResponseReader;
 using ProtoEntity = caosdb::entity::v1alpha1::Entity;
 using grpc::CompletionQueue;
 
+MultiResultSet::MultiResultSet(MultiTransactionResponse *response) {
+  auto *responses = response->mutable_responses();
+  for (auto sub_response : *responses) {
+    switch (sub_response.wrapped_response_case()) {
+    case WrappedResponseCase::kRetrieveResponse:
+      this->entities.push_back(std::make_unique<Entity>(
+        sub_response.mutable_retrieve_response()->release_entity()));
+      break;
+    case WrappedResponseCase::kInsertResponse:
+      this->entities.push_back(
+        std::make_unique<Entity>(sub_response.release_insert_response()));
+      break;
+    case WrappedResponseCase::kDeleteResponse:
+      this->entities.push_back(
+        std::make_unique<Entity>(sub_response.release_insert_response()));
+      break;
+    default:
+      // TODO(tf) Updates
+      break;
+    }
+  }
+}
+
 [[nodiscard]] auto UniqueResult::GetEntity() const -> const Entity & {
   const Entity *result = this->entity.get();
   return *result;
@@ -268,7 +291,7 @@ auto Transaction::WaitForIt() const noexcept -> TransactionStatus {
       this->result_set = std::make_unique<UniqueResult>(deletedIdResponse);
     } break;
     default:
-      // TODO(tf)
+      // TODO(tf) Error and Update
       break;
     }
   } else {