Hello Thomas,
Thank you for the reply. I had a look at release notes and I think the
changes below are unrelated to my problem.
On the other hand, I had a look at the source code and I would kindly
ask you if the scenario below can happen; because, if it happens, then
I think we have an issue :
Source code snippets ( from h2 version 1.0.69 ) :
TableData.java ( line 275 ) :
275 public void removeRow(Session session, Row row) throws
SQLException {
276 lastModificationId = database.getNextModificationDataId();
277 if (database.isMultiVersion()) {
278 if (row.getDeleted()) {
279 throw
Message.getSQLException(ErrorCode.CONCURRENT_UPDATE_1, getName());
280 }
281 int old = row.getSessionId();
282 int newId = session.getId();
283 if (old == 0) {
284 row.setSessionId(newId);
285 } else if (old != newId) {
286 throw
Message.getSQLException(ErrorCode.CONCURRENT_UPDATE_1, getName());
287 }
288 }
................
Record.java ( line 65 onwards ) :
65 public void setSessionId(int sessionId) {
66 this.sessionId = sessionId;
67 }
68
69 public int getSessionId() {
70 return sessionId;
71 }
72
73 /**
74 * This record has been committed. The session id is reset.
75 */
76 public void commit() {
77 this.sessionId = 0;
78 }
......
Scenario :
Suppose there are two threads, T1 and T2, which read and update
'value' in a table, for a certain row with key = 123
Let's assume that initially value = 0 ( zero )
T1 :
T1.1 begin tran
T1.2 select value from my_table where key = 123
T1.3 newValue = value + 5
T1.4 update my_table set value = newValue where key = 123
T1.5 commit
T2 :
T2.1 begin tran
T2.2 select value from my_table where key = 123
T2.3 newValue = value + 8
T2.4 update my_table set value = newValue where key = 123
T2.5 commit
Now, if MVCC = true and both threads T1 & T2 are running, we should
have a final result of 13, as either 0 + 5 + 8 or 0 + 8 + 5.
However, I think, we might end up having either 5 or 8 , in the
following situation :
step 1 : Thread T1 executes T1.1 & T1.2 , and so it reads value = 0
step 2 : Thread T2 executes T2.1 & T2.2 , and so it also reads value =
0
step 3 : Thread T1 executes T1.3 and calculates newValue = value + 5 =
5
step 4 : Thread T2 executes T2.3 and calculates newValue = value + 8 =
8
step 5 : Thread T1 executes T1. 4 and updates row with newValue = 5
step 6 : Thread T1 executes T1.5 and so it commits the transaction; in
this moment, row.sessionId becomes 0 ( zero ) ( Record.java line 77 )
step 7 : Thread T2 executes T2.4 & T2.5 and so it updates the row with
newValue = 8 because, somehow, the code below _might_ work this way :
275 public void removeRow(Session session, Row row) throws
SQLException { <=== 'this' is T2
276 lastModificationId = database.getNextModificationDataId();
277 if (database.isMultiVersion()) { <=== yes, returns true
278 if (row.getDeleted()) { <=== returns false; the row is
not deleted
279 throw
Message.getSQLException(ErrorCode.CONCURRENT_UPDATE_1, getName());
280 }
281 int old = row.getSessionId(); <=== returns '0' ( zero )
because T1 committed ( at step 6 above )
282 int newId = session.getId(); <=== returns some non-zero
Id ( '1122334455' )
283 if (old == 0) { <== returns true , as per the line 281
result
284 row.setSessionId(newId); <== so this line executes
and row gets assigned T2's session Id
285 } else if (old != newId) { <=== _but_ this else branch
is not executed, so the old != newId check is skipped
286 throw
Message.getSQLException(ErrorCode.CONCURRENT_UPDATE_1, getName()); <==
so this does not happen
287 }
288 }
289 <=== so T2 continues here and eventually commits the row
with an updated newValue = 8
Can you, please, confirm if this is a problem or it is I who got
something wrong here ? ( I hope I do .... )
Thank you very much, indeed.
Ionut
On Aug 20, 4:24 am, "Thomas Mueller" <[EMAIL PROTECTED]>
wrote:
> Hi,
>
> Maybe the problem is solved in a newer version of H2 - could you try
> 1.0.77 (2008-08-16)? Two problems related with MVCC have been solved
> (CREATE TABLE AS SELECT did not work correctly in the multi-version
> concurrency mode., Multi version concurrency (MVCC): when a row was
> updated or deleted, but this change was rolled back, the row was not
> visible by other sessions if no index was used to access it.) see
> alsohttp://www.h2database.com/html/changelog.html
>
> If this doesn't help, could you send me or post the .trace.db file?
>
> Regards,
> Thomas
>
> On Fri, Aug 15, 2008 at 6:23 AM,ivrusuboca<[EMAIL PROTECTED]> wrote:
>
> > Thanks guys, for your replies.
>
> > Thotheolh : unfortunately I cannot post the entire stuff 'cause it
> > contains corporate information ... etc ... None the less I will try to
> > get the most out of the h2 data and post it back.
>
> > Thomas : here are the connection details :
>
> > jdbc:h2:${DATASTORE_DIR}/${env}/
> > xstabcache;TRACE_LEVEL_FILE=3;CACHE_SIZE=$
> > {CACHE_SIZE};LOCK_MODE=3;MVCC=true;MULTI_THREADED=0
>
> > Regards,
> > Ionut
>
> > On Aug 8, 9:04 pm,ivrusuboca<[EMAIL PROTECTED]> wrote:
> >> Hi guys,
>
> >> I am having thrown the following exception ( layers are : H2,
> >> Hibernate & my app ) :
>
> >> org.h2.jdbc.JdbcSQLException: Concurrent update in table
> >> X_ACK_MESSAGE: another transaction has updated or deleted the same row
> >> [90131-74]
> >> at org.h2.message.Message.getSQLException(Message.java:103)
> >> at org.h2.message.Message.getSQLException(Message.java:114)
> >> at org.h2.message.Message.getSQLException(Message.java:77)
> >> at org.h2.table.TableData.removeRow(TableData.java:287)
> >> at org.h2.table.Table.updateRows(Table.java:356)
> >> at org.h2.command.dml.Update.update(Update.java:131)
> >> at
> >> org.h2.command.CommandContainer.update(CommandContainer.java:69)
> >> at org.h2.command.Command.executeUpdate(Command.java:203)
> >> at
> >> org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:
> >> 137)
> >> at
> >> org.h2.jdbc.JdbcPreparedStatement.executeBatch(JdbcPreparedStatement.java:
> >> 1049)
> >> at
> >> com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:
> >> 1723)
> >> at
> >> org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:
> >> 48)
> >> at
> >> org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:34)
> >> at
> >> org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:
> >> 2408)
> >> at
> >> org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:
> >> 2312)
> >> at
> >> org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:
> >> 2612)
> >> at
> >> org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:
> >> 96)
> >> at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:
> >> 279)
> >> at
> >> org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
> >> at
> >> org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
> >> at
> >> org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:
> >> 298)
> >> at
> >> org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:
> >> 27)
> >> at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
> >> at
> >> org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
> >> at
> >> org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:
> >> 106)
> >> <my app here>
>
> >> So the message suggests that another transaction has updated or
> >> deleted the same row I am trying to update here. But, unfortunatley, I
> >> am unable to trace ( via <myh2>.trace.db file ) any such transaction,
> >> although I have the tracelog on level 3 therefore I see all SQLs
> >> printed out.
>
> >> Do you have any suggestion as how to find the other transaction that
> >> it is interfering with this one above ?
>
> >> Thank you very much, indeed.
> >> -ivrusuboca-
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "H2
Database" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/h2-database?hl=en
-~----------~----~----~----~------~----~------~--~---