2015-01-01 6 views
0

Мне нужно сделать POC, который использует JTA XA Resource с MySQL в ядре Java (не в Интернете), без использования каких-либо фреймворков. Все статьи и примеры показывают фиксацию с использованием одного источника данных. Хотя я сделал распределенную транзакцию с двумя базами данных, но у меня есть сомнения/запросы в «Двухфазном коммите» с использованием XA Resource. Мой код:JTA XAResource несколько баз данных: что делать, если двухфазное принятие завершается после подготовки

public static void main(String[] args) { 
    DataSource dataSourceRemote = ConnectionManager.getDatasourceRemote(); 
    DataSource dataSourceLocal = ConnectionManager.getDatasourceLocal(); 
XAResource xaRes; 
    XAResource xaRes2; 
    XID xid, xid2; 
    try { 

     XADataSource xaDataSourceLocal; 
     XAConnection xaCon; 

     //XID xid; 
     Connection con; 
     Statement stmt; 
     int ret; 

     XADataSource xaDataSourceRemote; 
     XAConnection xaCon2; 

     //XID xid2; 
     Connection con2; 
     Statement stmt2; 
     int ret2;xaDataSourceLocal = (XADataSource) dataSourceLocal; 

     xaCon = xaDataSourceLocal.getXAConnection("root", "root"); 
     con = xaCon.getConnection(); 
     stmt = con.createStatement(); 
     xaRes = xaCon.getXAResource(); 

     xaDataSourceRemote = (XADataSource) dataSourceRemote; 

     xaCon2 = xaDataSourceRemote.getXAConnection("root", "root"); 
     con2 = xaCon2.getConnection(); 
     stmt2 = con2.createStatement(); 
     xaRes2 = xaCon2.getXAResource(); 

     con.setAutoCommit(false); 
     con2.setAutoCommit(false); 

     xid = new XID(100, new byte[] {0x01}, new byte[] {0x02}); 
     xid2 = new XID(101, new byte[] {0x02}, new byte[] {0x03}); 

     xaRes.start(xid, XAResource.TMNOFLAGS); 
     String query = "insert into emp values (12, \"Sanjay\", \"12345\", 100000)"; 
     System.out.println(query); 
     stmt.executeUpdate(query); 


     xaRes2.start(xid2, XAResource.TMNOFLAGS); 
     stmt2.executeUpdate("insert into emp values (11, \"Nikhil\", \"12345\",  100000)"); 


     xaRes2.end(xid2, XAResource.TMSUCCESS); 
     xaRes.end(xid, XAResource.TMSUCCESS);ret = xaRes.prepare(xid); 
     ret2 = xaRes2.prepare(xid2); 

     if(ret == XAResource.XA_OK && ret2 == XAResource.XA_OK){ 
      xaRes2.commit(xid2, false); 
      xaRes.commit(xid, false); 

     } 
     con.close(); 
     con2.close(); 
     xaCon.close(); 
     xaCon2.close(); 

     con2.close(); 
    } catch (XAException e) { 

     e.printStackTrace();    
    } 
    catch (SQLException e) { 

     e.printStackTrace(); 
    } 
} 

}

Теперь мои запросы:

1) Есть ли необходимость определить два Xids, как если бы я заменить Xid2 с Xid, код работает отлично

2) Я взял отладку в строке: if (ret == XAResource.XA_OK & & ret2 == XAResource.XA_OK), когда готово возвращает XAResource.XA_OK, и условие получилось истинным как для xresources. Теперь, если я остановлю службу MySQL на своей локальной машине, xaRes2.commit (xid2, false); будет успешно работать и xaRes.commit (xid, false); будет бросать исключение XA. В этом случае «двухфазное принятие» терпит неудачу, поскольку один источник данных находится в противоречивом состоянии. Мой вопрос: я делаю это правильно или есть другой способ сделать это?

3) Что такое фактическое использование восстановления, так как в этом случае одна сделка получила поручены и другие не удалось после того, как вернулся успешно подготовка

ответ

0

1) Я думаю, что вы запутались. XA-транзакция идентифицируется/ссылается на XID. Поэтому, если вы используете два xID, у вас будет две транзакции XA.

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

2) Обычно у вас есть менеджер транзакций, который позаботится об этом и очистке в случае ошибки. В этом случае вам в основном нужно реализовать это, и вам нужно позаботиться обо всех ошибках, что не является тривиальным. Чтобы убедиться, что часть восстановления работает правильно, вам необходимо протестировать все различные сценарии ошибок. Oracle, например, позволяет пропустить фиксацию в разных точках кода кода фиксации для тестирования. Я не уверен, что mysql обладает такой же способностью.

3) Восстановление требуется, например, если одна из ветвей вашей транзакции XA терпит неудачу или если вы совершили сделку, и один из ваших менеджеров ресурсов не может совершить.

В общем случае, если вы используете базу данных, такую ​​как Mysql в вашем случае, вам нужна база данных для реализации протокола xa, поскольку в противном случае восстановление, скорее всего, не будет работать правильно. Конечно, вам нужно будет сообщить базе данных, что это транзакция xa.

+0

Hello Steave, MySQL реализует XA, поскольку я получил источник данных из 'MysqlDataSource dataSource = new MysqlXADataSource();'. И согласно сценарию в пункте нет. (2) если один источник данных находится в переходном состоянии и выбрасывает исключение XA, как я могу поместить его в согласованное состояние? или как я могу восстановить его в этом сценарии? Еще одна вещь, вы можете помочь мне в этом также [ссылка] (http://stackoverflow.com/questions/27854352/warning-executing-transaction-with-0-enlisted-resource-bitronix) – atv

 Смежные вопросы

  • Нет связанных вопросов^_^