java.lang.ArrayIndexOutOfBoundsException: i=272 size=272

153 views
Skip to first unread message

yusuf soysal

unread,
Dec 19, 2011, 3:02:20 AM12/19/11
to H2 Database

Hello,

We encountered an exception today which I couldn't solve by myself.
Maybe you may direct to the solution.
We have been using H2 for about a year, and this is the first time we
had this exception. We are inserting records to a table from a thread,
and read the records from another thread.

This is the SQL script of my table:

CREATE TABLE IF NOT EXISTS NOTIFICATION_MESSAGES(
MESSAGE_ID VARCHAR(30) PRIMARY KEY,
NOTIFICATION_MESSAGE_SEQUENCE VARCHAR(100),
VARIANT_ID VARCHAR(50),
DST_MSISDN VARCHAR(20),
SRC_MSISDN VARCHAR(20),
STATUS INT,
ERROR_CODE VARCHAR(50),
ERROR_DESC VARCHAR(100),
SMSC_ID VARCHAR(50),
CONF_RECEIVE_DATE TIMESTAMP,
NOTF_RECEIVE_DATE TIMESTAMP,
REGISTER_ID VARCHAR(50),
PULLDATE TIMESTAMP,
CONF_SEQUENCE_ID VARCHAR(50),
CONF_SOCKET_ALIAS VARCHAR(50),
RETRY_COUNT INT,
NEXT_PULL_DATE TIMESTAMP
)

I opened my datasource with MVCC=TRUE and FILE_LOCK=NO (the reason I
don't use file locking is I had other problems back a year ago. This
is how I solved it :( ).

And this is how I query it:

StringBuilder sql = new StringBuilder();
sql.append(" SELECT MESSAGE_ID, NOTIFICATION_MESSAGE_SEQUENCE,
VARIANT_ID, DST_MSISDN, SRC_MSISDN, ");
sql.append(" STATUS, ERROR_CODE, ERROR_DESC, SMSC_ID,
CONF_RECEIVE_DATE, NOTF_RECEIVE_DATE, ");
sql.append(" REGISTER_ID, RETRY_COUNT, conf_sequence_id,
conf_socket_alias, next_pull_date ");
sql.append(" FROM NOTIFICATION_MESSAGES ");
sql.append(" WHERE PULLDATE IS NULL ");
sql.append(" AND (NEXT_PULL_DATE IS NULL OR NEXT_PULL_DATE < ?) ");
sql.append(" LIMIT " + limit);
sql.append(" FOR UPDATE ");

getJdbcTemplate().query(sql.toString(), new Object[] {new Date()},
MatchedNotificationRowMapper.INSTANCE);

And then mark the records that I queried:

StringBuilder sql = new StringBuilder();
sql.append(" UPDATE NOTIFICATION_MESSAGES SET PULLDATE = NOW() WHERE
MESSAGE_ID = ? ");

getJdbcTemplate().batchUpdate(sql.toString(), new
BatchPreparedStatementSetter() {

@Override
public void setValues(PreparedStatement ps, int i) throws
SQLException {
MatchedNotification mn = (MatchedNotification)
messages.get(i);
ps.setString(1, mn.getMessageId());
}

@Override
public int getBatchSize() {
return messages.size();
}
});

Since I need transaction support while querying this table, I wrap the
query in spring transaction:

transactionTemplate.execute(new TransactionCallback() {

@Override
public Object doInTransaction(TransactionStatus status) {
NfOperationsDao nfOperationsDao =
enablerNfOperationsDaoManager.findDao(messageTypeId);
List<IMatchedNotification> notifications =
nfOperationsDao.getMessages(numberOfMessages); // this is where I
fetched the records
nfOperationsDao.markMessagesAsPulled(notifications); // this is
where I mark the records

return notifications;
}
});

After 3 days of our latest performance test, H2 started to throw an
ArrayIndexOutOfBoundsException.

2011-12-19 09:50:48 NotfMessageGuiderModuleImpl [ERROR] Could not
commit JDBC transaction; nested exception is
org.h2.jdbc.JdbcSQLException: General error:
"java.lang.ArrayIndexOutOfBoundsException: i=272 size=272"; SQL
statement:
COMMIT [50000-153]
org.springframework.transaction.TransactionSystemException: Could not
commit JDBC transaction; nested exception is
org.h2.jdbc.JdbcSQLException: General error:
"java.lang.ArrayIndexOutOfBoundsException: i=272 size=272"; SQL
statement:
COMMIT [50000-153]
at
org.springframework.jdbc.datasource.DataSourceTransactionManager.doCommit(DataSourceTransactionManager.java:
270)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:
754)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:
723)
at
org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:
147)
at
com.t.c.service.impl.NotfMessageServiceImpl.pullMessagesFromDb(NotfMessageServiceImpl.java:
29)
at
com.t.c.modules.impl.NotfMessageGuiderModuleImpl.buildMessageMap(NotfMessageGuiderModuleImpl.java:
157)
at
com.t.c.modules.impl.NotfMessageGuiderModuleImpl.moduleProcess(NotfMessageGuiderModuleImpl.java:
51)
at
com.t.c.modules.impl.BaseColumbusModuleImpl.onMessageProcess(BaseColumbusModuleImpl.java:
23)
at com.t.c.modules.job.NotfMessageGuiderJob
$NotfMessageGuiderJobImpl.doWork(NotfMessageGuiderJob.java:30)
at com.t.c.modules.job.ColumbusBaseJob
$ColumbusJobImpl.run(ColumbusBaseJob.java:108)
Caused by: org.h2.jdbc.JdbcSQLException: General error:
"java.lang.ArrayIndexOutOfBoundsException: i=272 size=272"; SQL
statement:
COMMIT [50000-153]
at
org.h2.message.DbException.getJdbcSQLException(DbException.java:327)
at org.h2.message.DbException.get(DbException.java:156)
at org.h2.message.DbException.convert(DbException.java:279)
at org.h2.command.Command.executeUpdate(Command.java:216)
at org.h2.jdbc.JdbcConnection.commit(JdbcConnection.java:418)
at
com.t.c.data.adapter.h2.H2ConnectionImpl.commit(H2ConnectionImpl.java:
46)
at
org.springframework.jdbc.datasource.DataSourceTransactionManager.doCommit(DataSourceTransactionManager.java:
267)
... 9 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: i=272 size=272
at org.h2.util.IntArray.get(IntArray.java:67)
at
org.h2.store.PageOutputStream.initNextData(PageOutputStream.java:93)
at org.h2.store.PageOutputStream.write(PageOutputStream.java:
130)
at org.h2.store.PageLog.write(PageLog.java:529)
at org.h2.store.PageLog.commit(PageLog.java:549)
at org.h2.store.PageStore.commit(PageStore.java:1422)
at org.h2.engine.Database.commit(Database.java:1685)
at org.h2.engine.Session.commit(Session.java:460)
at
org.h2.command.dml.TransactionCommand.update(TransactionCommand.java:
46)
at
org.h2.command.CommandContainer.update(CommandContainer.java:69)
at org.h2.command.Command.executeUpdate(Command.java:212)
... 12 more

Can you tell me why we had this exception and how to resolve it?

H2 version: 1.3.153
Operation System: SunOS 5.10 Generic_144489-01 i86pc i386 i86pc
Environment: Weblogic
Start Script: java -server -Xrs -Xms512m -Xmx3072m -XX:PermSize=256m -
XX:MaxPermSize=512m -Xloggc:M1-MAN1.gc -verbose:gc -XX:+PrintGCDetails
-XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+UseParallelGC -
XX:ParallelGCThreads=5 -Xverify:none -Dweblogic.Name=TST-M1-MAN1 -
Dweblogic.management.username=weblogic -Xdebug -Xnoagent -
Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n -
Dweblogic.webservice.i18n.charset=utf-8 -
Dweblogic.management.server=http://10.200.60.134:1111 -
Djava.security.policy=/usr/local/wls103/wlserver_10.3/server/lib/
weblogic.policy weblogic.Server


Thank you.

Thomas Mueller

unread,
Dec 19, 2011, 1:22:41 PM12/19/11
to h2-da...@googlegroups.com
Hi,

FILE_LOCK=NO (the reason I
don't use file locking is I had other problems back a year ago. This
is how I solved it :( ).

Hm, you may have solved the other problems, but most likely this is the root cause for the ArrayIndexOutOfBoundsException.

I guess what happened is: you have opened the database multiple times in different processes. Because of using FILE_LOCK=NO, the database didn't detect it. Both processes wrote to the database file in an unsynchronized way, which caused the corruption.

I suggest not to use FILE_LOCK=NO.

Regards,
Thomas
Reply all
Reply to author
Forward
0 new messages