public function findOrSpawnUser(LtiLaunchData $launchData)
    {
        $dataModel = ModelManager::getModel();
        $transactionSafe = $this->getOption(self::OPTION_TRANSACTION_SAFE);
        
        if (!$dataModel instanceof \core_kernel_persistence_smoothsql_SmoothModel || !$transactionSafe) {
            // Non-transaction safe approach (default).
            $taoUser = $this->findUser($launchData);
            if (is_null($taoUser)) {
                $taoUser = $this->spawnUser($launchData);
            }
            
            return $taoUser;
        } else {
            // Transaction safe approach.
            $platform = $dataModel->getPersistence()->getPlatform();            
            $retry = 0;
            $maxRetry = $this->getRetryOption();
            $previousIsolationLevel = $platform->getTransactionIsolation();
            
            while ($retry <= $maxRetry) {
                // As the following instructions produce a Critical Section, we need SERIALIZABLE SQL Isolation Level.
                $platform->setTransactionIsolation(\common_persistence_sql_Platform::TRANSACTION_SERIALIZABLE);
                $platform->beginTransaction();
                
                try {
                    $taoUser = $this->findUser($launchData);
                    
                    if (is_null($taoUser)) {
                        $taoUser = $this->spawnUser($launchData);
                    }
                    
                    $platform->commit();
                    
                    return $taoUser;
                } catch (\common_persistence_sql_SerializationException $e) {
                    // Serialization failures may occur. Useful reading below:
                    // - https://www.postgresql.org/docs/9.5/static/transaction-iso.html
                    // - https://dev.mysql.com/doc/refman/5.7/en/innodb-deadlocks.html
                    
                    // Will be a WARNING for Sprint-64 only. After this point, will go to DEBUG level.
                    \common_Logger::w('SQL Serialization Failure occured in ' . __CLASS__ . '::' . __LINE__ . ' while finding or spawing LTI Ontology user. Retried ' . $retry . ' times.');
                    $retry++;
                } catch (\Exception $e) {
                    if ($platform->isTransactionActive()) {
                        \common_Logger::d('Rollbacking LTI Ontology user transaction.');
                        $platform->rollback();
                    }
                    
                    // Log original exception.
                    \common_Logger::e($e->getMessage());
                    
                    throw new LtiException('LTI Ontology user could not be created. Process had to be rolled back.', 0, $e);
                } finally {
                    // Reset isolation level to previous one!
                    $platform->setTransactionIsolation($previousIsolationLevel);
                }
            }
        }
    }