transaction problem

What I am trying to do is to prevent lost update from happening.
In first java script I put a xquery update inside a “serializable” transaction, like following:
TConnectionFactory connectionFactory = TConnectionFactory.getInstance();
connection = connectionFactory.newConnection( DATABASE_URI );
TLocalTransaction transaction = connection.useLocalTransactionMode();
connection.setIsolationDegree(TIsolationDegree.SERIALIZABLE);
accessor = connection.newXMLObjectAccessor(TAccessLocation.newInstance(collection ) ,
TJDOMObjectModel.getInstance() );
String query_string = “update replace input()/note[@id=“20”]/a with eric”;
TXQuery xquery = TXQuery.newInstance(query_string);
TResponse response = accessor.xquery( xquery );
Thread.sleep(10000);
connection.close();

Then in the second java script, I have the exact same code.
When I run the first code, since it has Thread.sleep(10000), it will hang a little time, then I run the second script, to my supprise, both code will finish successfully, which is a lost update.

However, if in the second java code, I don’t put the xquery in a transaction, it actually will fail since it says that it cann’t get a lock on the document.

Hello Eric,

if I understand your posting then the Tamino behavior is perfectly ok.
There are two situations two be explained:

1st: Two transactions in session context (local transaction mode).
The first transaction performs an update. In terms of locks, it aquires an exclusive lock on the document to be updated. This lock will not be released before end of transaction.
The second transaction performs the same update. In terms of locks, it tries to acquire an exclusive lock on the same document, which is not immediately available. Therefore, this transaction waits until the first one terminates. Then the lock becomes available and the second transaction can continue. That means, you should also observe, that the second transaction hangs until the first one terminates.
What you see is not a “lost update” in terms of transaction theory but a sequential execution of two independent transactions.

Please note, within the local transaction mode the default behavior is waiting for locks that are not availabe.

2nd: One transaction in local transaction mode, a second transaction not in local transaction mode.
Again, the first transaction performs its update and acquires the exclusive lock on the document to be updated.
Again, the second transaction tries to perform the same update but cannot immediately acquire the required exclusive lock. Now, in global transaction mode, the system returns immediately with an error message, saying that the update was not successful because some resource (the document to be updated, in fact in your example it should be the doctype containing the document to be updated) could not be locked. The second transaction fails without having executed an update.
Please note, within global transaction mode the default behavior is NOT to wait for locks but return immediately with an error if a lock cannot be granted.

If needed it is possible in both cases to change the waiting/non-waiting behavior using the lockWait option.

Best regards,

Michael

thanks a lot. That helps.

  1. According to you, a global transaction is a transaction not in a session. However, according to Tamino’doc, a global transaction is a transaction affecting more than 1 database servers.

  2. Where can you modify the “failed” behavior to “wait” when a global transaction try to update a document which is being updated by other transactions

  3. Today, I just tried to use two script to update different document under the same doctype. However, one of them failed by complaining that it cann’t get a lock on the document being updated by the other process. Why is this happening? I suppose that two process can update different document under same doctype at the same time. Both scripts is not in any transaction control script. They are all session-less

Thanks

  1. I’m sorry for my miswording. In terms of the Java API I meant autocommit mode instead of global transaction mode.

  2. You can switch between the “failed” and “wait” behavior only within Tamino. In the HTTP X-machine programming interface it is the _LOCKWAIT request parameter which can be set to “yes” or “no”.

  3. It is possible to concurrently update two documents in the same doctype. I presume you are using XQuery update. It is important to note that XQuery first selects all documents to be updated. For all documents that qualifiy based on indexes XQuery needs to acquire at least read locks which will be upgraded to exclusive locks if a document in fact will be updated. In your scenario, I assume that your first update succeeds and the second update has the updated document in the index processor’s result set. Thus it tries to lock it, which is not possible because of the concurrent exclusive lock of the updating request. An appropriate index for the update query’s predicate might help.
    If you are not using XQuery update, please provide a more detailed description.

Hope this helps

Michael

Hi,
You are right, I am using XQuery to udpate. However, I don’t think my xquery update statements will select two set of document overlaping with eachother.
The doctype I query against has a doctype “Notebook”. And each document under this doctype has a unique id within this “Notebook” element.
The queries I have in my process are:

update insert attribute xcomments {“emma”} into
input()/Notebook[@id=“abc”]//i[@xid=“305”]

update insert attribute xcomments {“emma”} into
input()/Notebook[@id=“def”]//i[@xid=“305”]

as you can see, these two queries select 2 totally different document based on the “id” of root element.

Thanks

I assume you do not have an index on Notebook/@id. In that case the index processor cannot do a good job, it selects all available documents. Afterwards, a post processing step can find out that only some documents are to be updated.
But, post processing is an expensive task and we cannot wait with locking of all result documents until post processing has been finished. To increase the system’s query througput we lock the results of the index processor. This causes to your locking problem.
Having an index on Notebook/@id the index processor can select and lock only the documents to be updated.

Best regards,

Michael

thanks for the help. I created an index on “id” and it works. However, I found some interesting things.

When I just create an index on attribute “id” of element “Notebook”,
query /Notebook[@id=“a”]/div uses the index.
however, //Notebook[@id=“a”]/div doesn’t. I have to create another multi-path index on “id”, then it works. as well as query //Notebook[@id=“a”]//div

however, I just can’t make the query /Notebook[@id=“a”]//div to use the index on “id”.
do you have any suggestion on this?

Thanks