2016-01-25 33 views
0

这是JBoss的standalone.xmlJBoss数据源故障转移在单个事务中如何处理失败?

<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> 

我的连接细节我想处理故障转移的一个角落情况后persist()在通话过程中得到EntityManager对象,连接丢失。故障切换选项不会切换到同一事务中的下一个数据库,它会在下一个事务中切换到活动连接。我尝试了这样的事情:(Catch Exception并获取更新的bean对象)

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查找获取新bean不会包含更新的新连接,并引发异常。这导致该交易的数据丢失。

请建议如何处理“连接失去后获取EntityManager和持续之前”的角落案例。

回答

0

我认为这是不可能实现的。问题是,如果内部数据库转换被中止,那么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应用服务器和抛出异常那么我认为唯一可能的解决方案是重复整个更新操作。

相关问题