Не удается начать транзакцию на сервере MS SQL Express с помощью ADO

Я хочу обновить некоторые строки в базе данных MS SQL с C++. Проблема в том, что я не могу создать транзакцию. Каждый раз, когда я пытаюсь выполнить Ado::Connection::BeginTrans, я получаю сообщение об ошибке:

A request to establish a connection with the transaction manager was denied.

Я установил новую копию SQL Server 2017 Express Edition на свой локальный компьютер (Win 10 Pro) и создал новую БД под названием test.

Строка подключения:

Provider=SQLNCLI11;Server=SNAIL\SQLEXPRESS;Database=test;Trusted_Connection=yes; 

Что мне делать, чтобы избавиться от этой ошибки?

Обновлено:

Часть исходного кода:

#import <msado15.dll> rename_namespace("ADO2"), raw_interfaces_only, raw_native_types, named_guids, no_smart_pointers

const auto connection_string = L"Provider=sqloledb;Data Source=SNAIL\\SQLEXPRESS;Initial Catalog=test;Integrated Security=SSPI";

// create connection
Ref<ADO2::_Connection> m_DbConnection;
m_DbConnection->put_Mode(ADO2::adModeReadWrite);
m_DbConnection->put_ConnectionTimeout(5);
m_DbConnection->Open(connection_string, nullptr, nullptr, ADO2::adConnectUnspecified)


class InAdoTransaction {
private:
    Ref<ADO2::_Connection>  m_DbConnection;
    bool m_Commited;

public:
    InAdoTransaction(ADO2::_Connection *Connection) {
        m_DbConnection = Connection;
        m_Commited = false;

        long transaction_level;
        HRESULT er = m_DbConnection->BeginTrans(&transaction_level);
        ASSERT(er == S_OK);
    }

    ~InAdoTransaction() {
        if (!m_Commited) {
            Rollback();
        }
    }

    void Rollback() {
        m_DbConnection->RollbackTrans();
    }

    void Commit() {
        m_DbConnection->CommitTrans();
        m_Commited = true;
    }
};


// usage
HRESULT FUNC StoreMetadata()
{
    HRESULT er = S_OK;

    Ref<ADO2::_Recordset> rst;

    InAdoTransaction transaction(m_DbConnection);

    if (FAILED(m_DbConnection->Execute(QUERY_TRUNCATE_METADATA_TABLE, nullptr, 0, OUT(rst)))) {
        return E_CANNOT_STORE_METADATA;
    }

    ...

    transaction.Commit();
}

Разместите свой код. Транзакции работают с ADO. В конце концов, это технология, которой более 25 лет.

Panagiotis Kanavos 22.05.2019 15:38

Некоторый код может помочь. Документы предлагают пример, который действительно ужасен, но может дать вам ключ к пониманию того, что вы делаете неправильно. (Однако определенно не используйте поставщика sqloledb, который он вам там показывает; sqlncli11 подойдет, или более новый msoledbsql, который требует отдельной установки.)

Jeroen Mostert 22.05.2019 15:39

Вы перезагружались после установки SQL Server Express? Работает ли служба координатора распределенных транзакций?

Bacon Bits 22.05.2019 15:41

Вы, вероятно, не должен тоже используете SQLNCLI11. Это устарело и все новые разработки были направлены на драйверы ODBC и OLEDB. ADO в любом случае работает поверх OLEDB, поэтому использование клиента OLEDB с "Provider='sqloledb' вообще не изменит код.

Panagiotis Kanavos 22.05.2019 15:42

Эта конкретная ошибка означает, что каким-то образом код пытался запустить транзакцию распределенный. Для этого требуется DTC и, вероятно, нет то, что вам нужно. Простая команда BEGIN TRAN не требует DTC. Connection.BeginTrans() также не должен нуждаться в DTC.

Panagiotis Kanavos 22.05.2019 15:44

С другой стороны, использование, например, связанного сервера в запросе требует распределенной транзакции и попытается использовать MS DTC.

Panagiotis Kanavos 22.05.2019 15:47

Я также пробовал 'sqloledb', но поведение такое же. + Я добавил фрагмент кода к вопросу.

zdenek 22.05.2019 16:08
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
0
7
315
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я наконец нашел решение. Вся проблема была в наборе записей, который я создал для таблиц INFORMATION_SCHEMA.TABLES и INFORMATION_SCHEMA.VIEWS. Тип блокировки этого набора записей был установлен на LockType::adLockReadOnly, что и вызвало проблему. Я изменил его на LockType::adLockOptimistic и теперь все работает как часы.

Но очень жаль, что провайдер возвращает такое вводящее в заблуждение сообщение об ошибке.

Другие вопросы по теме