cancel
Showing results for 
Search instead for 
Did you mean: 

Why commit in transaction don't do this until the webscript is finished?

spilby
Confirmed Champ
Confirmed Champ
I'm implementing a java backed webscript. In my description doc the transaction is specified like required.


<transaction>required</transaction>


I have something like this:


UserTransaction trx = serviceRegistry.getTransactionService().getUserTransaction(false);
try {
   trx.begin();
   Alfresco OPERATION 1
   Alfresco OPERATION 2
   trx.commit();
} catch(Throwable e) {
   trx.rollback();
   …
}


And after, in other part of the code, I have something like this:


UserTransaction trx = serviceRegistry.getTransactionService().getUserTransaction(false);
try {
   trx.begin();
   Alfresco OPERATION 3
   Alfresco OPERATION 4
   trx.commit();
} catch(Throwable e) {
   trx.rollback();
   …
}


If the OPERATION 4 not works, I want to have a rollback only of the operations 3 and 4. And the operation 1 and 2 commit ok. Is the reason I have different transactions.

But the webscript don't do this. When the operation 4 fails (I induce a exception there to test it), the webscript do the rollback of all: 1, 2, 3 and 4. I don't understand why, if I do the commit after operation 2.

This trx.commit is parcial? The real commit is doing when the webscript ends? Somebody knows the reason, please?

Thanks a lot!



4 REPLIES 4

kaynezhang
World-Class Innovator
World-Class Innovator
It is because you are using
 
UserTransaction trx = serviceRegistry.getTransactionService().getUserTransaction(false);
,It will use existing transaction(your webscript transaction ) instead of creating new one .
You can try following code

UserTransaction trx = serviceRegistry.getTransactionService().getNonPropagatingUserTransaction(false);
try {
   trx.begin();
   Alfresco OPERATION 1
   Alfresco OPERATION 2
   trx.commit();
} catch(Throwable e) {
   trx.rollback();
   …
}



UserTransaction trx = serviceRegistry.getTransactionService().getNonPropagatingUserTransaction(false);
try {
   trx.begin();
   Alfresco OPERATION 3
   Alfresco OPERATION 4
   trx.commit();
} catch(Throwable e) {
   trx.rollback();
   …
}

And make sure not throw exception in these two code sections(because you set required in your webscript transaction definition) .

spilby
Confirmed Champ
Confirmed Champ
Oks, if I understand all ok, transaction required gives me a unique transaction for my webscript. If I change it to transaction none, the transaction do the commit every time I call a commit() method, and the rollbacks the same. And the code works like I need. It's all right?

Then, if I use transaction required, and the same transaction with getUserTransaction false, the commit method not works? I thank that simply the commit works on the same transaction. Sorry with the confusion, I dont understand the difference, it's my fault.

One question more about this… Why throwing an exception isn't a good practice if I use transaction required? What problem could give me?

The other solution is change to nonPropagationUserTransaction method. First I used this method, but gives me a problem. I have a cluster of two running Alfresco. If I do on the same folder an operation on one node and then do another operation on the other it gives me a transaction concurrency problem. We think that the problem was that the second one try to obtain the transaction of the first, and our alfresco couldn't transfer the transaction in the cluster. When I change to getUserTransaction false, all works ok. Is the reason that I prefer the solution changing only the transaction required in the xml.

Thanks!

kaynezhang
World-Class Innovator
World-Class Innovator

1.   If you set transaction required for your webscript,webscript framework will create a transaction for you ,in this situation 
 getUserTransaction 
and
 getNonPropagatingUserTransaction 
will work differently:
a)   
getUserTransaction
will use the existiong transaction that webscript framework created ,so all your code in
  Alfresco OPERATION 1,Alfresco OPERATION 2,Alfresco OPERATION 3, Alfresco OPERATION 4 
all execute in the same transaction ,any exceptions throwed in  Alfresco OPERATION 1 to Alfresco OPERATION 4 will cause the whole transaction rollback.
b)   
getNonPropagatingUserTransaction
  will create a new transaction ,
Alfresco OPERATION 1 and  Alfresco OPERATION 2 
will execute in a           second transaction that is different from webscript transaction which can be commited and rollback separately,
Alfresco OPERATION 3 and  Alfresco                 OPERATION 4 
will run in the third transaction
2.   If you set transaction none for your webscript,then
 getUserTransaction 
and
 getNonPropagatingUserTransaction 
will work the same ,both will create a new transaction for their own.


No,I did not mean throwing an exception isn't a good practice ,it depends on your requirment .If you use transaction required and  throw an exception for example in

   Alfresco OPERATION 1
   Alfresco OPERATION 2
,it will also cause your webscript transaction rollback,which might be not what you need.

spilby
Confirmed Champ
Confirmed Champ
Thanks kaynezhang! Your post has been very useful. Now I undestand the differences perfectly. Thanks again! Smiley Happy