Как получить соединения JDBC, полученные из источника данных JNDI, для участия в транзакции UserTransaction с использованием Weblogic 10.3? - PullRequest
5 голосов
/ 18 декабря 2009

В настоящее время я получаю как пользовательскую транзакцию, так и источник данных с сервера Weblogic 10.3 с использованием JNDI.

Я установил для источника данных значение «Поддержка глобальных транзакций» и для использования «Регистрация последнего ресурса»

Я надеялся, что при запуске UserTranscation, а затем при получении соединения JDBC из источника данных соединение будет участвовать в транзакции.

Похоже, что это не так, и мои операторы вставки сразу фиксируются, и откат транзакции не имеет никакого эффекта.

Верны ли мои предположения выше?

Может ли кто-нибудь указать мне направление какой-либо документации или образцов на то, как этого добиться?

Большое спасибо заранее

UPDATE:

В соответствии с запросом здесь приведен набросок кода, который я использую:

private void doSomething() {
Connection conn = null;
try {
    Hashtable env = new java.util.Hashtable();
    env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
    env.put(javax.naming.Context.PROVIDER_URL,"t3://localhost:8080");
    InitialContext ctx = InitialContext(env));

    UserTransaction transaction = null;
    transaction = (UserTransaction) ctx.lookup("java:comp/UserTransaction");

    DataSource dataSource = (DataSource) context.lookup("jdbc/xxxxx/DataSource");
    conn = dataSource.getConnection();
    transaction.begin();
    // JDBC code goes here
    transaction.commit();
} catch(Exception e) {
    // TODO
    if (transaction != null) {
    try {
    transaction.rollback();
    } catch (Exception ex) {
    // TODO
    }
} finally {
  if (con != null) {
    conn.close
  }
}
}

ОБНОВЛЕНИЕ 2:

Чтобы решить эту проблему, мне пришлось сделать 2 вещи:

  1. Измените порядок кода, чтобы сначала начать пользовательскую транзакцию, а затем получить соединение из хранилища данных (как указал Паскаль Thivent).

  2. Измените источник данных, на который ссылается «jdbc / xxxxx / DataSource», на XADatasource. Это связано с тем, что я вызывал код внутри пользовательской транзакции, которая использовала другой источник данных, который уже был настроен для поддержки LLR, и, как указывает Pascal Thivent ниже, в транскатации может участвовать только один источник данных LLR.

Я принял ответ Паскаля Тивента ниже, потому что он объяснил обе эти проблемы.

1 Ответ

2 голосов
/ 18 декабря 2009

Да, ваши предположения верны, и, согласно Создание источников данных JDBC с поддержкой LLR , ваш источник данных выглядит правильно настроенным.

Получаете ли вы соединение после запуска пользовательской транзакции? Можете ли вы показать свой код или псевдокод?

ОБНОВЛЕНИЕ: Как упомянуто в Соображения по программированию и ограничения для источников данных LLR :

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

Итак, не могли бы вы попробовать это:

transaction.begin(); //start the global tx before calling getConnection()
conn = dataSource.getConnection(); 
...
transaction.commit();

UPDATE2: Не совсем понятно, откуда приходит второе соединение (ваш псевдокод этого не показывает). Тем не менее, согласно тем же Программным соображениям и ограничениям для источников данных LLR :

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

На самом деле, без полностью репрезентативного примера, я чувствую себя немного похожим на ходьбу в темноте:)

...