cancel
Showing results for 
Search instead for 
Did you mean: 

JCR-RMI and transactions

adepue
Champ in-the-making
Champ in-the-making
If this should be in the JCR-RMI plugin forum, let me know.  Anyway, we currently embed Alfresco within our app, and would like to move it out as a separate service.  We would also like to move to the standard JCR API in the process.  It looks like, for now, that means JCR over RMI.  However, we make heavy use of transactions and need Alfresco to participate in them (we are currently using Spring + JOTM, but will be moving away from JOTM shortly).  Does JCR-RMI support this in any way?  Forum searches are turning up similar questions, but no answers.  Also, does Alfresco cope with the fact that RMI calls in a JCR session can happen over different threads?

Thanks in advance.
6 REPLIES 6

rdanner
Champ in-the-making
Champ in-the-making
If this should be in the JCR-RMI plugin forum, let me know.  Anyway, we currently embed Alfresco within our app, and would like to move it out as a separate service.  We would also like to move to the standard JCR API in the process.  It looks like, for now, that means JCR over RMI.  However, we make heavy use of transactions and need Alfresco to participate in them (we are currently using Spring + JOTM, but will be moving away from JOTM shortly).  Does JCR-RMI support this in any way?  Forum searches are turning up similar questions, but no answers.  Also, does Alfresco cope with the fact that RMI calls in a JCR session can happen over different threads?

Thanks in advance.

Anyway, we currently embed Alfresco within our app, and would like to move it out as a separate service.  We would also like to move to the standard JCR API in the process.

Alfresco is a/supports a "standard JCR API" – you use the interfaces to address the repository not the implementation.  I assume you actually mean a standard adapter to get JCR plugged in to your app? 

Anyway, we currently embed Alfresco within our app, and would like to move it out as a separate service.

Do you need to connect to a remote JCR or is everything taking place on the same machine? 

However, we make heavy use of transactions and need Alfresco to participate in them (we are currently using Spring + JOTM, but will be moving away from JOTM shortly).

I don't  know the answer to this question but my understanding of the Afresco transaction model is to keep everything ACID in the core.  I am interested in the answer you get on this.  If I had to take a swag at the answer I'd guess you may have some issues.

Also, does Alfresco cope with the fact that RMI calls in a JCR session can happen over different threads?
You are saying you are going to share the same session with multiple threads?  There is a one Session / Thread limitation on the implementation side

Some of the suggested models are: 
but not all of these are possible without some work.  Session pooling etc is an option but you have to deal with the threading ramifications.
http://mail-archives.apache.org/mod_mbox/jackrabbit-dev/200606.mbox/%3C510143ac0606200348w5bea57a0q5...

rdanner
Champ in-the-making
Champ in-the-making
If this should be in the JCR-RMI plugin forum, let me know.  Anyway, we currently embed Alfresco within our app, and would like to move it out as a separate service.  We would also like to move to the standard JCR API in the process.  It looks like, for now, that means JCR over RMI.  However, we make heavy use of transactions and need Alfresco to participate in them (we are currently using Spring + JOTM, but will be moving away from JOTM shortly).  Does JCR-RMI support this in any way?  Forum searches are turning up similar questions, but no answers.  Also, does Alfresco cope with the fact that RMI calls in a JCR session can happen over different threads?

Thanks in advance.

Anyway, we currently embed Alfresco within our app, and would like to move it out as a separate service.  We would also like to move to the standard JCR API in the process.

Alfresco is a "standard API" – you use the interfaces to address the repository not the implementation.  I assume you actually mean a standard adapter to get JCR plugged in to your app? 

Anyway, we currently embed Alfresco within our app, and would like to move it out as a separate service.

Do you need to connect to a remote JCR or is everything taking place on the same machine? 

However, we make heavy use of transactions and need Alfresco to participate in them (we are currently using Spring + JOTM, but will be moving away from JOTM shortly).

I don't  know the answer to this question but my understanding of the Afresco transaction model is to keep everything ACID in the core.  I am interested in the answer you get on this.  If I had to take a swag at the answer I'd guess you may have some issues.

Also, does Alfresco cope with the fact that RMI calls in a JCR session can happen over different threads?
You are saying you are going to share the same session with multiple threads?  There is a one Session / Thread limitation on the implementation side

Some of the suggested models are: 
but not all of these are possible without some work.  Session pooling etc is an option but you have to deal with the threading ramifications.
http://mail-archives.apache.org/mod_mbox/jackrabbit-dev/200606.mbox/%3C510143ac0606200348w5bea57a0q5...

adepue
Champ in-the-making
Champ in-the-making
You are saying you are going to share the same session with multiple threads?  There is a one Session / Thread limitation on the implementation side
No, what I meant is that when the client of an RMI proxied interface invokes methods against that proxy (all in the same thread on the client side), most RMI implementations I've worked with end up invoking the proxied method from different threads on the server side.  So, if the client does something like this:
- Client Thread 1 -
service.method1();
service.method2();
service.method3();
It can end up like this on the server (mostly depending on server load):
- Server Thread 1 -
service.method1();
- Server Thread 2 -
service.method2();
- Server Thread 1 -
service.method3();
At any rate, thread locals end up being very unreliable once you export something via RMI, and I know that Spring transaction management, Hibernate session management, and Acegi authentication management all use thread locals to maintain transaction, session, and security context.

rdanner
Champ in-the-making
Champ in-the-making
You are saying you are going to share the same session with multiple threads?  There is a one Session / Thread limitation on the implementation side
No, what I meant is that when the client of an RMI proxied interface invokes methods against that proxy (all in the same thread on the client side), most RMI implementations I've worked with end up invoking the proxied method from different threads on the server side.  So, if the client does something like this:
- Client Thread 1 -
service.method1();
service.method2();
service.method3();
It can end up like this on the server (mostly depending on server load):
- Server Thread 1 -
service.method1();
- Server Thread 2 -
service.method2();
- Server Thread 1 -
service.method3();
At any rate, thread locals end up being very unreliable once you export something via RMI, and I know that Spring transaction management, Hibernate session management, and Acegi authentication management all use thread locals to maintain transaction, session, and security context.

Ah.. sorry about that – I see what you are getting at.  Speaking of thread locals… what on earth is the fetish in the java community for using this techique?  It's not exactly a small design decision… as you said it can have serious implications on how your implementation can be used.

adepue
Champ in-the-making
Champ in-the-making
… Speaking of thread locals… what on earth is the fetish in the java community for using this techique?  It's not exactly a small design decision… as you said it can have serious implications on how your implementation can be used.
I don't like thread locals a whole lot, but Java provides few (any?) alternatives if you want to have some kind of context for your executing code.  Context like current transaction, current authentication, etc.  I suppose you could always pass needed context around as parameters to every method you invoke… but that's just not practical for obvious reasons.
One idea as an alternative to thread local would be "stack local" variables.  They would work in a similar way to thread local, except they would be local to the current method on the call stack, and any methods invoked within the current method (and so on, to any depth).  Thus, a method could setup a transaction, put it into a stack local variable, and any methods executed from there are all done within that transaction.  Once the main method unwinds, the transaction goes out of scope.  With that in place, the next thing I'd like to see is the ability to manipulate the call stack: detach it from the thread, store it away, pull it out later, reattach it to any thread, continue execution, etc.  This would make continuations possible, along with thread migration, etc.  With these two things, all sorts of amazing stuff could be done… but these two things would require changes to the JVM.  Oh well…

rdanner
Champ in-the-making
Champ in-the-making
… Speaking of thread locals… what on earth is the fetish in the java community for using this technique?  It's not exactly a small design decision… as you said it can have serious implications on how your implementation can be used.
I don't like thread locals a whole lot, but Java provides few (any?) alternatives if you want to have some kind of context for your executing code.  Context like current transaction, current authentication, etc.  I suppose you could always pass needed context around as parameters to every method you invoke… but that's just not practical for obvious reasons.
One idea as an alternative to thread local would be "stack local" variables.  They would work in a similar way to thread local, except they would be local to the current method on the call stack, and any methods invoked within the current method (and so on, to any depth).  Thus, a method could setup a transaction, put it into a stack local variable, and any methods executed from there are all done within that transaction.  Once the main method unwinds, the transaction goes out of scope.  With that in place, the next thing I'd like to see is the ability to manipulate the call stack: detach it from the thread, store it away, pull it out later, reattach it to any thread, continue execution, etc.  This would make continuations possible, along with thread migration, etc.  With these two things, all sorts of amazing stuff could be done… but these two things would require changes to the JVM.  Oh well…

No doubt that is powerful behavior. 

My contention is that I see the pattern used everywhere and I am not sure it is always necessary or that it is or that the implications on the use of the code that leverages the technique are always fully considered.  OSIV seems to be a very popular pattern these days – of course it’s not the only pattern that works.  Its a real trade off – passing arguments around can create heavy interfaces for which the real problem is cohesion of implementation assumptions and at the same time Thread Local has it's own drawbacks in that implies a certain set of use restrictions in terms of threading and remoting etc.  Thread locals imply protocol and that comes with a cost just as the heaviness of passing context around in the method signature does.  Another wonderful (not so wonderful) aspect of TLs in the web environment is that we pool threads so it’s really important to make sure you are properly recycling.

You can't please everyone I guess.  For my part I discourage their use here as much as possible.  If some one wants to use a TL, I want to know why and there better be a darn good reason for it.