Каково поведение тега cfransaction Coldfusion при обращении к нескольким базам данных?

Документация по Coldfusion (я использую CF8) гласит:

Изменения данных, запрашиваемых запросами, не фиксируются в источнике данных до тех пор, пока все действия в блоке транзакции не будут выполнены успешно.

Но в нем также говорится:

В блоке транзакции вы можете записывать запросы в несколько баз данных, но вы должны зафиксировать или откатить транзакцию в одну базу данных, прежде чем писать запрос в другую.

У меня есть несколько транзакций в моей базе кода, которые имеют доступ к 2 базам данных как для выбора, так и для обновления / вставки. Код предполагает, что все запросы либо будут выполнены успешно, либо все они будут откатаны. Но я не знаю, правда ли это, основываясь на строке в документации, которая гласит: "но вы должны зафиксировать или откатить транзакцию в одну базу данных, прежде чем писать запрос в другую".

Каково поведение, если запись в первую базу данных завершается успешно, а последующая запись в другую базу данных не выполняется? Первый откатится?

2 ответа

Решение

Документация означает, что вы должны поставить <cftransaction action="commit"> после запросов к одной базе данных, прежде чем вы сможете перейти к использованию другого источника данных. Он выдаст ошибку, если обнаружит, что у вас есть <cfquery> теги с различными источниками данных внутри транзакции без использования фиксации. Обратитесь к документации базы данных для точной поддержки транзакций, поскольку CFML через драйвер базы данных отправляет только команды транзакций от вашего имени, он не несет ответственности за их выполнение или поведение. Включите ведение журнала JDBC в вашей базе данных, чтобы увидеть это в действии.

Не будет работать:

  <cftransaction action="begin">

    <cfquery datasource="foo">
    select * from foo_test
    </cfquery>

    <cfquery datasource="bar">
    select * from bar_test
    </cfquery>

  </cftransaction>

Буду работать

<cftransaction action="begin">

    <cfquery datasource="foo">
    select * from foo_test
    </cfquery>

  <cftransaction action="commit"><!-- Commit before switching DSNs --->

   <cfquery datasource="bar">
    select * from bar_test
    </cfquery>

</cftransaction>

Если вы используете имена трех частей для множественного доступа к базе данных через один источник данных, управление транзакциями будет работать.

<cftransaction action="begin">

    <cfquery datasource="foo">
    INSERT INTO foo_test ( id )
    VALUES ( 70 )
    </cfquery>

    <!-- insert into the bar database via the foo datasource --->
    <cfquery datasource="foo">
    INSERT INTO bar.dbo.bar_test (id )
    VALUES ( 'frank' ) <!-- Fails because not an int and the prior insert into foo is rolled back -->
    </cfquery>

</cftransaction>

Поведение по умолчанию для CFTransaction заключается в том, что все записи будут откатываться, если в блоке транзакции есть исключение. Таким образом, если один запрос не выполняется, все запросы откатываются.

Это только в том случае, если база данных поддерживает фиксации и откаты на основе языка управления транзакциями, подмножества SQL.

Однако вы можете детально контролировать работу транзакции CF, помимо поведения по умолчанию, включая такие функции, как точки сохранения и вложенные транзакции.

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