В чем разница между Jet OLEDB: режим фиксации транзакции и Jet OLEDB: синхронизация фиксации пользователя? - PullRequest
2 голосов
/ 30 декабря 2010

Хотя оба параметра Jet / OLE DB являются относительными хорошо задокументированы Я не могу понять разницу между этими двумя параметрами подключения:

Первый:

Jet OLEDB: режим фиксации транзакции (DBPROP_JETOLEDB_TXNCOMMITMODE)

Указывает, записывает ли Jet данные на диск синхронно или асинхронно при фиксации транзакции.

Второй:

Jet OLEDB: синхронизация фиксации пользователя (DBPROP_JETOLEDB_USERCOMMITSYNC)

Указывает, записываются ли изменения, сделанные в транзакциях, в синхронном или асинхронном режиме.

Какая разница?Когда использовать какой?

Ответы [ 2 ]

6 голосов
/ 03 января 2011

Это очень долго, поэтому вот короткий ответ:

Не устанавливайте ни один из них. Настройки по умолчанию для этих двух параметров, вероятно, будут правильными. Первый, Transaction Commit Mode, управляет неявными транзакциями Jet и применяется вне явных транзакций и имеет значение YES (асинхронный). Второй контролирует, как Jet взаимодействует со своей временной базой данных во время явной транзакции и имеет значение NO (синхронно). Я не могу вспомнить ситуацию, в которой вы хотели бы переопределить значения по умолчанию здесь. Однако вам может потребоваться установить их явно, если вы работаете в среде, в которой параметры ядра базы данных Jet были изменены по умолчанию.

Теперь длинное объяснение:

Я пробежался по множеству ресурсов, связанных с Jet, чтобы узнать, смогу ли я узнать, какова ситуация здесь. Кажется, что две константы OLEDB отображаются на эти два члена SetOptionEnum объекта DAO DBEngine верхнего уровня (подробности здесь для тех, у кого нет доступного файла справки Access):

  dbImplicitCommitSync 
  dbUserCommitSync 

Эти параметры существуют для переопределения параметров реестра по умолчанию для ядра базы данных Jet во время выполнения для любого конкретного соединения или для постоянного изменения сохраненных настроек для него в реестре. Если вы загляните в Реестр для HLKM \ Software \ Microsoft \ Jet \ X.X \, то увидите, что под ключом для версии Jet, которую вы используете, есть ключи, из которых два являются:

  ImplicitCommitSync
  UserCommitSync

Руководство программиста ядра базы данных Jet 3.5 определяет их:

  • ImplicitCommitSync: значение Yes указывает, что Microsoft Jet будет ожидать завершения фиксации. Значение, отличное от Да, означает, что Microsoft Jet будет выполнять фиксацию асинхронно.

  • UserCommitSync: если для параметра задано значение Да, Microwsoft Jet будет ожидать завершения фиксации. Любое другое значение означает, что Microsoft Jet будет выполнять фиксацию асинхронно.

Так вот, это просто подтверждение того, что вы уже сказали. Огорчает то, что первый имеет значение по умолчанию NO, а второй по умолчанию YES. Если бы они действительно контролировали одну и ту же вещь, вы ожидали бы, что они будут иметь одинаковое значение, или что конфликтующие значения будут проблемой.

Но ключ на самом деле оказывается в названии, и он отражает историю Jet в отношении того, как записи данных фиксируются внутри и вне транзакций. До Jet 3.0 Jet по умолчанию устанавливал синхронные обновления вне явных транзакций, но начиная с Jet 3.0, транзакции IMPLICIT были введены и использовались по умолчанию (с оговорками в Jet 3.5 - см. Ниже). Таким образом, один из этих двух параметров применяется для фиксации ВНЕШНИХ транзакций (dbImplicitCommitSync), а другой - для фиксации ВНУТРИ транзакций (dbUserCommitSync). Наконец, я нашел подробное объяснение этого в Руководстве программиста Jet Database Engine (стр. 607-8):

UserCommitSynch Параметр UserCommitSynch определяет внесены ли изменения как часть явная транзакция ... записана в база данных в синхронном режиме или асинхронный режим . Значением по умолчанию ... является Да, которое указывает асинхронный режим. Это не рекомендуется изменить это значение потому что в синхронном режиме, есть нет гарантии, что информация была записывается на диск перед вашим кодом переходит к следующей команде.

ImplicitCommitSync По умолчанию, когда выполнение операций, которые добавляют, удалить или обновить записи за пределами явные транзакции, Microsoft Jet автоматически выполняет внутренний транзакции под названием неявные транзакции , которые временно сохраняют данные в кэш-памяти, а затем позже записать данные как кусок в диск. Параметр ImplicitCommitSync определяет, были ли внесены изменения используя неявные транзакции записывается в базу данных синхроннорежим или асинхронный режим.Значением по умолчанию ... является Нет, которое указывает, что эти изменения записываются в базу данных в асинхронном режиме;это обеспечивает лучшую производительность.Если вы хотите, чтобы неявные транзакции записывались в базу данных в синхронном режиме, измените значение ... на Да.Если вы измените значение ... вы получите поведение, подобное Microsoft Jet версий 2.x и более ранних, когда вы не использовали явные транзакции.Однако это также может значительно снизить производительность, поэтому не рекомендуется изменять значение этого параметра.

Примечание. Больше нет необходимости использовать явные транзакции для повышения производительности Microsoft Jet.Приложение базы данных, использующее Microsoft Jet 3.5, должно использовать явные транзакции только в ситуациях, когда может потребоваться откат изменений.Micosoft Jet теперь может автоматически выполнять неявные транзакции для повышения производительности при добавлении, удалении или изменении записей.Однако неявные транзакции для операторов SQL DML были удалены в Microsoft Jet 3.5 ... см. «Удаление неявных транзакций для операторов SQL DML» далее в этой главе.

Этот раздел:

Удаление неявных транзакций для операторов SQL DML Даже несмотря на всю работу в Microsoft Jet 3.0 по устранению транзакций с целью повышения производительности, операторы SQL DML по-прежнему помещались в неявные транзакции.В Microsoft Jet 3.5 операторы SQL DML не помещаются в неявную транзакцию.Это существенно повышает производительность при выполнении операторов SQL DML, которые влияют на многие записи данных.

Хотя это изменение обеспечивает существенное улучшение производительности, оно также вносит изменения в поведение операторов SQL DML.При использовании Microsoft Jet 3.0 и предыдущих версий, которые используют неявные транзакции для операторов SQL DML, оператор SQL DML откатывается, если какая-либо часть оператора не выполнена.При использовании Microsoft Jet 3.5 некоторые записи могут быть зафиксированы оператором SQL DML, а другие - нет.Примером этого может быть превышение кеша Microsoft Jet.Данные в кеше записываются на диск, а следующий набор записей изменяется и помещается в кеш.Поэтому, если соединение разорвано, возможно, что некоторые записи были сохранены на диск, а другие - нет.Это то же самое поведение, что и при использовании подпрограмм DAO для обновления данных с помощью явной транзакции в Microsoft Jet 3.0.Если вы хотите избежать такого поведения, вам нужно добавить явные транзакции вокруг оператора SQL DML, чтобы определить набор работы, и вы должны пожертвовать приростом производительности.

Еще не запутались?Я, конечно, согласен.

Мне кажется, что ключевым моментом является то, что dbUserCommitSync, по-видимому, контролирует способ записи Jet в базу данных TEMPORARY, которую он использует для размещения транзакций EXPLICIT, тогда как dbImplicitCommitSync относится к тому, где Jet использует неявные транзакцииВне явной транзакции.Другими словами, dbUserCommitSync управляет поведением движка внутри цикла BeginTrans / CommitTrans, а dbImplicitCommitSync управляет поведением Jet в отношении асинхронизации / синхронизации вне явных транзакций.

Теперь, что касается «удаленияРаздел «Неявные транзакции»: мое прочтение состоит в том, что неявные транзакции применяются к обновлениям, когда вы просматриваете набор записей вне транзакции, но больше не применяются к оператору SQL UPDATE вне транзакции.Само собой разумеется, что оптимизация, которая улучшает производительность построчных обновлений, была бы хорошей и фактически не сильно помогла бы с пакетным обновлением SQL, которое уже будет чертовски быстрым (условно говоря).

Также обратите внимание, что тот факт, что это можно сделать обоими способами, позволяет DoCmd.RunSQL выполнять неполные обновления. Таким образом, команда SQL, которая не будет работать с CurrentDB.Execute strSQL, dbFailOnError, может выполняться до завершения, если она выполняется с DoCmd.RunSQL. Если вы отключите DoCmd.SetWarnings, вы не получите сообщение об ошибке, и у вас не будет возможности откатиться до исходного состояния (или, если вас проинформируют об ошибках и решат совершить, в любом случае) ).

Итак, я думаю, что SQL, выполняемый через пользовательский интерфейс Access, по умолчанию заключен в транзакцию (именно так вы получаете запрос на подтверждение), но если вы отключите запросы и появится ошибка, вы получите применяются неполные обновления. Это не имеет ничего общего с настройками DBEngine - все зависит от того, как пользовательский интерфейс Access выполняет SQL (и есть возможность отключить или включить его).

Это отличается от обновлений в DAO, которые были заключены в неявные транзакции, начиная с Jet 3.0, но начиная с Jet 3.5, в неявные транзакции были включены только последовательные обновления - пакетные команды SQL (INSERT / UPDATE / DELETE) не.

По крайней мере, это мое чтение.

Итак, что касается проблемы в вашем реальном вопросе, при настройке вашего соединения OLEDB вы должны установить параметры для Jet DBEngine для этого соединения в соответствии с тем, что вы делали. Мне кажется, что настройки Jet DBEngine по умолчанию верны и не должны изменяться - вы хотите использовать неявные транзакции для изменений, когда вы просматриваете набор записей и обновляете по одной строке за раз (вне явной транзакции) , С другой стороны, вы можете обернуть все это в транзакцию и получить тот же результат, так что на самом деле это относится только к случаям, когда вы просматриваете набор записей и обновляете и не использовали явную транзакцию, а настройка по умолчанию кажется совершенно правильно для меня.

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

1 голос
/ 23 мая 2013

Вы могли бы подумать, что USERCOMMITSYNC=YES - это вариант для синхронной фиксации. И это причина путаницы.

Я потратил целую вечность на поиск в этой теме, потому что обнаружил, что поведение, которое я получал со старыми vb6 приложениями, было не таким, как я в .net oledb/jet4

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

В любом случае, я просматривал веб-сайт MSDN и обнаружил страницу с описанием ошибки «by design» в Jet3, которая транспонировала функциональность USERCOMMITSYNC, то есть значение NO получает синхронную фиксацию.

Поэтому MS устанавливает значение по умолчанию NO , и мы получаем синхронную фиксацию по умолчанию. Точно так же, как описано выше Дэвидом Фентоном. Поведение, которое мы все приняли, чтобы принять его.

Но затем документ объяснил, что поведение в oledb/Jet4 было изменено. В основном MS исправила свою ошибку, и теперь настройка USERCOMMITSYNC=YES делает то, что говорит.

Но они изменили значение по умолчанию? Я думаю не потому, что теперь мои явные транзакции NOT синхронно фиксируются в приложениях .Net с использованием oledb/jet4.

...