Oracle java.sql.SQLException:ORA-01002:XATransaction上的提取顺序不正确

Oracle java.sql.SQLException:ORA-01002:XATransaction上的提取顺序不正确,oracle,jdbc,transactions,glassfish,Oracle,Jdbc,Transactions,Glassfish,在相同的数据上,有时会抛出异常java.sql.SQLException:ORA-01002:fetch,但在大多数尝试中,都可以正常工作 运行在Glassfish 3.1.2.2上的Java应用程序。谁能解释一下,问题出在哪里 @Singleton @LocalBean @Startup @ConcurrencyManagement(ConcurrencyManagementType.BEAN) public class MarketCodesSingleton { @Resourc

在相同的数据上,有时会抛出异常java.sql.SQLException:ORA-01002:fetch,但在大多数尝试中,都可以正常工作

运行在Glassfish 3.1.2.2上的Java应用程序。谁能解释一下,问题出在哪里

@Singleton
@LocalBean
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class MarketCodesSingleton {

    @Resource(mappedName="jdbc/sss")
    private DataSource source;

    private volatile static Map<Interval, String> marketCodes;

    @PostConstruct
    @Schedule(minute="*/10", hour="*")
    public void fillMarketCodes() {
        try(Connection conn = source.getConnection()) {
            Map<Interval, String> marketCodesInt = new TreeMap<>();
            DaoFactory.getMarketCodesDao().fillMarketCodes(marketCodesInt, conn);
            marketCodes = Collections.unmodifiableMap(marketCodesInt);
            Logger.getLogger(getClass().getName()).log(Level.FINE, "MarketCodes updated");
        } catch (SQLException e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "fillMarketCodes exception",e);
            throw new EJBException("fillMarketCodes exception",e);
        }
    }

    public String getMarketCode(Long msisdn) {
        Interval interval = new Interval(msisdn);
        return marketCodes.get(interval);
    }

}
连接属性:

<jdbc-connection-pool 
    connection-creation-retry-interval-in-seconds="5" 
    datasource-classname="oracle.jdbc.xa.client.OracleXADataSource" 
    max-pool-size="200" 
    max-connection-usage-count="1000" 
    res-type="javax.sql.XADataSource" 
    steady-pool-size="0" 
    name="sss_pool" 
    connection-creation-retry-attempts="5">
      <property name="URL" value="jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = xxx.xxx.xxx.xxx)(PORT = xx)))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = xx)))"></property>
      <property name="Password" value="***"></property>
      <property name="User" value="***"></property>
</jdbc-connection-pool>

代码不完整,因此我只能猜测:

  • 光标已关闭,您试图再次获取
  • 您确实选择了更新并提交,然后尝试获取下一行

您的连接是否设置为自动提交?跨提交或回滚的获取可能会导致此异常


我还注意到,您的SQL并没有像在this和{}中那样被begin/end包围,以确定在遇到异常时是否处理了所有行

修改下面的代码以包含一个计数器i,以获取已处理的行并查找实际的行数

 int i=0;
  try{
 while (rs.next()) {
            Interval interval = new Interval(rs.getLong("from_no"), rs.getLong("to_no"));
            intervals.put(interval, rs.getString("market_code"));
            i=i+1;
        }
}
catch (Exception e)
{
 Logger.getLogger(getClass().getName()).log(Level.FINE, "the total rows processed"+ i);
 Statement stmt = null;
 String query = "select count(1) count_rows                   
               from market_codes";
    stmt = con.createStatement();
    ResultSet rs1 = stmt.executeQuery(query);
    rs1.next();
    String countRows = rs1.getString("count_rows");
    Logger.getLogger(getClass().getName()).log(Level.FINE,"Actual count of rows"+ countRows);
 }

这很奇怪,但通过删除注释@ConcurrencyManagement(ConcurrencyManagementType.BEAN),问题已经解决了


有人能解释一下吗?

正如您在方法fillMarketCodes中看到的,光标没有关闭。在这个方法的rs.next()上抛出异常,正如您在GET_MARKET_CODES过程中看到的,没有for update语句。我想看看getMarketCodes_SQL的定义。此外,我强烈建议为session.private静态最终字符串getMarketCodes_sql=“CALL SERVICE_PKG.GET_MARKET_CODES(?)”;那是行不通的。执行选择服务\u。。。从dual。只是为了添加,您可以为“rs”添加空检查吗?if(rs!=null)将有助于避免这些异常。请发布您的JDBC连接参数好吗?连接参数已添加到属性设置keepxaontilltxcomplete=“true”,“强制连接池保留物理数据库连接,并在整个事务处理过程中(即,直到分布式事务完成)保持与应用程序的连接。“您的问题可能是由于连接的XA事务上下文在结果集处理过程中发生更改而引起的。我在web上也找到了以下建议:)但我不确定它是否适合Glassfish。我认为,这只适用于Weblogic-
<jdbc-connection-pool 
    connection-creation-retry-interval-in-seconds="5" 
    datasource-classname="oracle.jdbc.xa.client.OracleXADataSource" 
    max-pool-size="200" 
    max-connection-usage-count="1000" 
    res-type="javax.sql.XADataSource" 
    steady-pool-size="0" 
    name="sss_pool" 
    connection-creation-retry-attempts="5">
      <property name="URL" value="jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = xxx.xxx.xxx.xxx)(PORT = xx)))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = xx)))"></property>
      <property name="Password" value="***"></property>
      <property name="User" value="***"></property>
</jdbc-connection-pool>
 int i=0;
  try{
 while (rs.next()) {
            Interval interval = new Interval(rs.getLong("from_no"), rs.getLong("to_no"));
            intervals.put(interval, rs.getString("market_code"));
            i=i+1;
        }
}
catch (Exception e)
{
 Logger.getLogger(getClass().getName()).log(Level.FINE, "the total rows processed"+ i);
 Statement stmt = null;
 String query = "select count(1) count_rows                   
               from market_codes";
    stmt = con.createStatement();
    ResultSet rs1 = stmt.executeQuery(query);
    rs1.next();
    String countRows = rs1.getString("count_rows");
    Logger.getLogger(getClass().getName()).log(Level.FINE,"Actual count of rows"+ countRows);
 }