繁体   English   中英

JBoss数据源故障转移如何处理单个事务中的故障?

[英]How does a JBoss datasource failover handle failure in single transaction?

这是我在JBoss standalone.xml连接详细信息

<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()期间获取EntityManager对象后,连接丢失。 故障转移选项不会在同一事务中切换到下一个数据库,而是在下一个事务中切换到活动连接。 我尝试过这样的事情:(捕获异常并获取更新的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之后以及在持久连接之前连接丢失”的极端情况。

我认为要实现目标几乎是不可能的。 问题是,如果内部数据库事务中止,那么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调用将与persist调用属于同一jta全局事务。 在这种情况下,事务被中止, persist调用将失败,并出现类似(PostgreSQL的情况)

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

我的意思是,如果Oracle jdbc驱动程序不能透明地处理与JBoss应用服务器的连接失败并向上抛出异常,那么我认为唯一可能的解决方案是重复整个更新操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM