2016-01-25 6 views
0

Это мое соединение деталей в JBoss standalone.xmlКак сбой при отказе данных в JBoss обрабатывается сбой в одной транзакции?

<connection-url> 
    jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=xx.1xx.119.1xx)(PORT=1521))(LOAD_BALANCE=on)(FAILOVER=on))(CONNECT_DATA=(SERVICE_NAME=XE))) 
</connection-url> 

Я хочу, чтобы справиться с угловой случай отказа, где после получения EntityManager объекта во время вызова persist(), соединение потеряно. Опция переадресации не переключается на следующую базу данных в той же транзакции, она переключается на активное соединение в следующей транзакции. Я пытался что-то вроде этого: (Поймать исключение и получить обновленный объект боб)

public EntityManager getEntityManager() { 
    try { 
     entityManager = getEntityManagerDao(Constant.JNDI_NFVD_ASSURANCE_ENTITY_MANAGER); 

    } catch (NamingException e) { 
     LOGGER.severe("Data could not be persisted."); 
     throw new PersistenceException(); 
    } 
    return entityManager.getEntityManager(); 
} 

/** 
* Inserts record in database. In case multiple connections/databases exist, one more attempt will be made to 
* insert record. 
* 
* @param entry 
*/ 
public void persist(Object entry) { 
    try { 
     getEntityManager().persist(entry); 
    } catch (PersistenceException pe) { 
     LOGGER.info("Could not persist data. Trying new DB connection."); 
     getEntityManager().persist(entry); 
    } 
} 

private static Object getJNDIObject(String path) throws NamingException { 
    Object jndiObject = null; 
    InitialContext initialContext = new InitialContext(); 
    jndiObject = initialContext.lookup(path); 
    return jndiObject; 
} 

private static AssuranceEntityManager getEntityManagerDao(String path) throws NamingException { 
    return (AssuranceEntityManager) getJNDIObject(path); 
} 

Но это один и не помогает. После обнаружения исключения, получение нового компонента с JNDI-поиском не содержит обновленного нового соединения и генерируется исключение. Это приводит к потере данных этой транзакции.

Пожалуйста, предложите, как обращаться с этим угловым корпусом «Соединение потерянного сообщения, получающего EntityManager и перед сохранением».

ответ

0

Я думаю, что совершенно невозможно, чего вы хотите достичь. Дело в том, что если внутренняя DB-трансляция прерывается, транзакция JTA находится в состоянии прерывания, и вы не можете продолжить ее.

Я ожидаю, что это отчасти похоже на этот случай

@Stateless 
public class TableCreator { 
    @Resource 
    DataSource datasource; 

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    public void create() { 
     try(Connection connection = datasource.getConnection()) { 
      Statement st = connection.createStatement(); 
      st.execute("CREATE TABLE user (id INTEGER NOT NULL, name VARCHAR(255))"); 
     } catch (SQLException sqle) { 
      // ignore this as table already exists 
     } 
    } 
} 

@Stateless 
public class Inserter { 
    @EJB 
    private TableCreator creator; 

    public void call() { 
     creator.create(); 

     UserEntity entity = new UserEntity(1, "EAP QE"); 
     em.persist(entity); 
    } 
} 

В случае, если таблица user существует, и вы бы использовать аннотацию @TransactionAttribute(TransactionAttributeType.REQUIRED) то create вызов будет частью той же JTA, глобальной транзакции, как вызов persist. Как в таком случае сделка была прекращена persist вызова потерпит неудачу, за исключением типа (PostGreSQL случая)

Caused by: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block 

Я имею в виду, если драйвер Oracle JDBC не может обрабатывать соединения не в состоянии прозрачно для сервера приложений JBoss и бросает исключение вверх, то я думаю, что единственным возможным решением является повторение всего действия по обновлению.