我正在使用Weblogic服务器,其中连接对象正在处理一个事务,其中同一连接实例正尝试使用另一个事务,那么现有事务无法完成,并引发事务错误,其中现有事务正在执行任何提交/回退操作以及新事务还使用多个使用同一连接对象的过程的提交/回滚操作。因此,有没有什么办法可以使用相同的连接对象来完成特定事务的会话,如果它完成了,那么对于新事务,新的会话应该开始以避免此错误

static {
    Context ctx = null;
    Hashtable ht = new Hashtable();
    ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
    ht.put(Context.PROVIDER_URL, "t3://localhost:7001");


    LOGGER.debug("con outside " + conn);
    ResultSet rs = null;
    try {
        ctx = new InitialContext(ht);
           javax.sql.DataSource ds
                = (javax.sql.DataSource) ctx.lookup("jndi/mynonXADatasource");


        // UserTransaction tx = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction");
         tx.begin();
         conn = ds.getConnection();
         conn.setAutoCommit(false);

    } catch (SQLException e) {
        LOGGER.error(e.getMessage());
    } catch (Exception e) {
        LOGGER.error(e.getMessage());
    }
}

public static Connection getdatasourceconnection() {

    try {
        if (null == conn || conn.isClosed()) {
            LOGGER.debug("Getting new Connection");
            conn = getNewConnection();
            return conn;
        }
         conn = obtainConnection();

    } catch (SQLException e) {
    }
    return conn;
}

private static Connection getNewConnection() {
    Context ctx = null;
    Hashtable ht = new Hashtable();

    ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
     ht.put(Context.PROVIDER_URL, "t3://localhost:7001");
    LOGGER.debug("con outside " + conn);

    Connection oraConn;        oraConn = null;
    try {
        ctx = new InitialContext(ht);
        javax.sql.DataSource ds
                = (javax.sql.DataSource) ctx.lookup("jndi/mynonXADatasource");

        //UserTransaction userTransaction=(UserTransaction)ctx.lookup ("jndi/mynonXADatasource");
         conn = ds.getConnection();
       conn.setAutoCommit(false);

         LOGGER.debug("con inside " + conn);
        LOGGER.debug("context " + ctx);

    } catch (SQLException e) {
        LOGGER.error(e.getMessage());
    } catch (Exception e) {
        LOGGER.error(e.getMessage());
    }
    return conn;
}

public static void closeConnection(Connection conn) {

    try {
        if (null != conn) {
            conn.close();
            conn = null;
        }
    } catch (SQLException ex) {
        LOGGER.error(ex.getMessage());
    }
}


我有15个存储过程调用,也使用了一些DML / DDL,如果我尝试使用相同的连接对象,我正在使事务处于准备阶段/已提交,就像这样,在存储过程中发生了提交操作,并且花费时间处理单个进程,而另一个进程(JMS)尝试使用相同的连接,则发生此事务错误。是否有任何方法可以使用相同的连接对象而不会导致事务失败,而不是每次都建议获取新的连接。

最佳答案

“我有15个存储过程调用,并且也使用了一些DML / DDL ...在存储过程中正在发生提交操作”


这似乎是您问题的症结所在。工作单元应该是单个事务。但是,看来您的体系结构是根据多个事务构建工作单元的(在数据库领域中,事务是两次提交之间的活动)。

至少您需要使用API​​(其中工作单元是单个存储过程)来为数据库层设置外观。该存储过程可以调用所有存储的proc并执行所有必需的DML,但是您只有一个数据库调用,它在一个会话中执行。完成之后,您可以开始从较低级别的过程中删除提交,并将事务管理放到它所属的位置:调用堆栈的顶部。

10-06 02:01