From: marc f. <mar...@jb...> - 2002-02-28 20:07:25
|
Ole, I never realized this until I was working on the client interceptors yesterday late at night. Our transaction object requires an external person to serialize itself. Namely the extraction of the transaction propagation context is done outside the transaction itself. This is a problem as it means that whoever is doing the serialization (in our case the JRMPInvoker layers) MUST know about the TM and that means we need to set the transaction monitor on them somehow. It works. If however we set the static entry on the Transaction implementation then the writeObject(Stream) call could take care of it own serialization (by getting the TPC and replacing the Tx by the TPC on the stream and that would be that... I think it would be a bit more self contained from a design standpoint. This lack of containment becomes very apparent as I put an interceptor layout on top of the client layers, not a biggy just FYI marcf |
From: Anatoly A. <akk...@cs...> - 2002-02-28 20:27:57
|
I need a few clarifications on this. DO you mean you want to have Transaction be Externalizable? So that Transaction upon externalization writes itself into the ObjectStream as a TPC? If this is what you mean, it would require wrapping any Tyrex Transaction object with a Proxy that would perform externalization? I am a bit confused here how would de-serialization happen? Anatoly On Thu, 28 Feb 2002, marc fleury wrote: > Ole, > > I never realized this until I was working on the client interceptors > yesterday late at night. Our transaction object requires an external person > to serialize itself. Namely the extraction of the transaction propagation > context is done outside the transaction itself. > > This is a problem as it means that whoever is doing the serialization (in > our case the JRMPInvoker layers) MUST know about the TM and that means we > need to set the transaction monitor on them somehow. It works. > > If however we set the static entry on the Transaction implementation then > the writeObject(Stream) call could take care of it own serialization (by > getting the TPC and replacing the Tx by the TPC on the stream and that would > be that... I think it would be a bit more self contained from a design > standpoint. > > This lack of containment becomes very apparent as I put an interceptor > layout on top of the client layers, not a biggy just FYI > > marcf > > > _______________________________________________ > Jboss-development mailing list > Jbo...@li... > https://lists.sourceforge.net/lists/listinfo/jboss-development > |
From: marc f. <mar...@jb...> - 2002-02-28 20:38:36
|
|I need a few clarifications on this. | |DO you mean you want to have Transaction be Externalizable? So that |Transaction upon externalization writes itself into the ObjectStream as a |TPC? precisely yes, |If this is what you mean, it would require wrapping any Tyrex Transaction |object with a Proxy that would perform externalization? I am a bit yes, a proxy or a wrapper or extension or something. |confused here how would de-serialization happen? Just the same way, we are talking about a "static" field for the TPC exporter and importer. The TPC importer is in the readObject and creates a local transaction object. The design for the transaction right now barfs everywhere, the transport layer has to be aware of it (ugh!) when really the transport layer should only be aware of serializable objects. in fact just have the Transaction lookup the JNDI entry for exporter and importer, that would be super sweet... neatly packaged and confined. It sort of looks bad to have an absolute unified layer and interceptors and all the modern patterns at play and then a fat "if transaction Manager bla bla bla then bla bla bla" in the middle of your transport layers. Does this make sense? marcf |> |
From: Anatoly A. <akk...@cs...> - 2002-02-28 21:06:31
|
> > Just the same way, we are talking about a "static" field for the TPC > exporter and importer. The TPC importer is in the readObject and creates a > local transaction object. > > The design for the transaction right now barfs everywhere, the transport > layer has to be aware of it (ugh!) when really the transport layer should > only be aware of serializable objects. > > in fact just have the Transaction lookup the JNDI entry for exporter and > importer, that would be super sweet... neatly packaged and confined. It > sort of looks bad to have an absolute unified layer and interceptors and all > the modern patterns at play and then a fat "if transaction Manager bla bla > bla then bla bla bla" in the middle of your transport layers. > > Does this make sense? It does make sense but here is what I don't particularly like about it, tell me if I'm wrong. I am mostly concerned about remote clients for whom the serialization actually happens. If we end up serializing this Tx Proxy with its Invoker that would actually ship only the TPC which it extracts, we would have to ship at least 1 more class on the wire (the Proxy). I don't know actually how serialization happen in terms of the class code being shipped, in which case the code for the Invoker would get shipped as well? Having a TPC and only serializing it is more lightweight (in fact, in my rewrite of Tyrex plugin I am only sending an integer, boolean and a few strings, besides other attempts to improve distributed performance). Low bandwidth connections to server is, perhaps, not on your agenda but it is something we are thinking about. Anatoly. > > marcf > |> > > |
From: marc f. <mar...@jb...> - 2002-02-28 21:14:17
|
|It does make sense but here is what I don't particularly like about |it, tell me if I'm wrong. it's not as bad, |I am mostly concerned about remote clients for whom the serialization |actually happens. If we end up serializing this Tx Proxy with its Invoker that is not correct in the case you are serializing the TX you are talking about the class description ("org.jboss.tm.TxSerializable") and the content of the serialization which in your case is that int you are talking about. The client and server already have the class definitions so if you are thinking about that it doesn't work this way if you already have the classes on the target. |that would actually ship only the TPC which it extracts, we would have to |ship at least 1 more class on the wire (the Proxy). I don't know actually |how serialization happen in terms of the class code being shipped, in |which case the code for the Invoker would get shipped as well? Having a |TPC and only serializing it is more lightweight (in fact, in my rewrite of |Tyrex plugin I am only sending an integer, boolean and a few strings, |besides other attempts to improve distributed performance). yeah... serialization is serialization and staying away from it *altogether* is the way to go (fundamentally speaking really, fuck distributed transactions for 5 years to come) and it won't cost that much more. |Low bandwidth connections to server is, perhaps, not on your agenda but it |is something we are thinking about. Again it is not that bad, really (plus you can just do the serialVersion thingy) and it is less important than having a transparent pluggable architecture which it is *everywhere* right now *but* the transactions. Ok? marcf |
From: Ole H. <os...@sp...> - 2002-03-02 12:12:08
|
Hi, Sorry for my late answer, I am a bit busy these days. marc fleury wrote: > I never realized this until I was working on the client interceptors > yesterday late at night. Our transaction object requires an external person > to serialize itself. Namely the extraction of the transaction propagation > context is done outside the transaction itself. Using external persons (TPCImporter and TCPFactory) in the transport is a conscious design decision. IMHO this is another design flaw in JTA: The methods in TPCImporter and TCPFactory should belong in the TransactionManager. Without them, the transport needs to have special knowledge about the transaction server to be able to move transaction contexts across the wire. Not that i really like this design. When i came up with it, I did a lot of careful thinking and studying of similar code trying to find something better - but I didn't. The alternative would be to use a Transaction wrapper that knows how to serialize itself, and to produce these wrappers we would have to use a TransactionManager wrapper that returns our Transaction wrappers instead of Transactions. So while the serialization in the transport would look a bit more beatiful, the cost would be that _every_ access to transactions in the server would have to go through a wrapper. But this would also mean a slower JBoss server for those who do not distribute their transactions across VMs at all. > This is a problem as it means that whoever is doing the serialization (in > our case the JRMPInvoker layers) MUST know about the TM and that means we > need to set the transaction monitor on them somehow. It works. Whoever is doing the serialization (and deserialization) ought not know about the TM. The only object needed to serialize the transaction is an instance of org.jboss.tm.TransactionPropagationContextExporter, and the only object needed to de-serialize is an instance of TransactionPropagationContextFactory. TPCImporter has a method that takes an untyped deserialized object and (tries to) convert it into an instance of javax.transaction.Transaction. TPCFactory does the opposite, it has a method that takes an instance of javax.transaction.Transaction and returns a serializable object. Both the TPCImporter and the TPCFactory can be looked up in JNDI after the TM MBean is started. > If however we set the static entry on the Transaction implementation then > the writeObject(Stream) call could take care of it own serialization (by > getting the TPC and replacing the Tx by the TPC on the stream and that would > be that... I think it would be a bit more self contained from a design > standpoint. I agree. But i cannot see how this could be done without either: 1) Using a wrapper for Transaction and TransactionManager that all local transaction access in the entire server would have to traverse. or 2) Hacking/patching every JTA implementation we want to use in JBoss to add the extra functionality to the Transaction implementation in that JTA implementation. I agree that the extra conversion step in the transport is more ugly than just letting serialization/de-serialization do its work - but we should carefully balance this against the cost of the alternatives. Also, this is only a problem for transports that do not directly support transaction context propagation. When using the IIOP transport (and most other transports that directly support transaction propagation) (Java-)serializing the Transaction would not work if we want to be compatible on the wire. Best Regards, Ole Husgaard. |
From: marc f. <mar...@jb...> - 2002-03-02 16:45:34
|
|IMHO this is another design flaw in JTA: The methods |in TPCImporter and TCPFactory should belong in the |TransactionManager. Without them, the transport needs |to have special knowledge about the transaction server |to be able to move transaction contexts across the wire. Yes that is a weakness |Not that i really like this design. When i came up with |it, I did a lot of careful thinking and studying of |similar code trying to find something better - but I didn't. | |The alternative would be to use a Transaction wrapper that |knows how to serialize itself, and to produce these wrappers Just put the import export code in the serialization pass it the JNDI names for importer exporter (or just the TM as you propose) |we would have to use a TransactionManager wrapper that |returns our Transaction wrappers instead of Transactions. No just extend the transaction to do the correct behavior |So while the serialization in the transport would look a |bit more beatiful, the cost would be that _every_ access |to transactions in the server would have to go through |a wrapper. not so, right now the pluggability is broken on the client side due to this hardcoded transport dependency. No need for a wrapper just an extension, either way the price is nothing. |But this would also mean a slower JBoss server for those |who do not distribute their transactions across VMs at all. nope |Whoever is doing the serialization (and deserialization) ought |not know about the TM. correct |The only object needed to serialize the transaction is an |instance of org.jboss.tm.TransactionPropagationContextExporter, |and the only object needed to de-serialize is an instance of |TransactionPropagationContextFactory. |TPCImporter has a method that takes an untyped deserialized |object and (tries to) convert it into an instance of |javax.transaction.Transaction. |TPCFactory does the opposite, it has a method that takes an |instance of javax.transaction.Transaction and returns a |serializable object. |Both the TPCImporter and the TPCFactory can be looked up |in JNDI after the TM MBean is started. well then that is the call we need in the write/read, no price to pay for the other and none of that nonsense. |> be that... I think it would be a bit more self contained from a design |> standpoint. | |I agree. And most importantly : for people who DON'T use the transactions we can remove it cleanly (pluggable, today it isn't and it is the only one). |But i cannot see how this could be done without either: |1) Using a wrapper for Transaction and TransactionManager | that all local transaction access in the entire server | would have to traverse. I don't agree, our native one can use the same object. |or |2) Hacking/patching every JTA implementation we want to use | in JBoss to add the extra functionality to the Transaction | implementation in that JTA implementation. The wrapper is for say Tyrex distributed transactions, it should really be a spec requirement that transactions are serializable (isn't that the case in JINI?) In any case stop talking about the "the cost of a method invocation in memory" when we are talking about distributed transactions, that price is 1 in a million (if not less :) |I agree that the extra conversion step in the transport is |more ugly than just letting serialization/de-serialization |do its work - but we should carefully balance this against |the cost of the alternatives. it's not only ugly, it breaks pluggability. marcf |
From: Ole H. <os...@sp...> - 2002-03-02 18:56:33
|
Hi, I am not sure if I understand you. Do you want all instances of javax.transaction.Transaction floating around the server to be instances of a JBoss-specific extension of this interface that knows how to serialize itself? marc fleury wrote: > |Not that i really like this design. When i came up with > |it, I did a lot of careful thinking and studying of > |similar code trying to find something better - but I didn't. > | > |The alternative would be to use a Transaction wrapper that > |knows how to serialize itself, and to produce these wrappers > > Just put the import export code in the serialization pass it the JNDI names > for importer exporter (or just the TM as you propose) If you do not want it in the Transaction implementation, as an extension to JTA, where then? > |we would have to use a TransactionManager wrapper that > |returns our Transaction wrappers instead of Transactions. > > No just extend the transaction to do the correct behavior We can only extend our own TM, for all others we would have to use wrappers for all instances of Transaction and TransactionManager. > |So while the serialization in the transport would look a > |bit more beatiful, the cost would be that _every_ access > |to transactions in the server would have to go through > |a wrapper. > > not so, right now the pluggability is broken on the client side due to this > hardcoded transport dependency. No need for a wrapper just an extension, > either way the price is nothing. > > |But this would also mean a slower JBoss server for those > |who do not distribute their transactions across VMs at all. > > nope Well, not if we hack our own JTA implementation to avoid using a wrapper, and use that. But how about all the other JTA implementations? > |> be that... I think it would be a bit more self contained from a design > |> standpoint. > | > |I agree. > > And most importantly : > for people who DON'T use the transactions we can remove it cleanly > (pluggable, today it isn't and it is the only one). I don't think that the current design breaks pluggability. See below. > |But i cannot see how this could be done without either: > |1) Using a wrapper for Transaction and TransactionManager > | that all local transaction access in the entire server > | would have to traverse. > > I don't agree, our native one can use the same object. Yes, we can change our own to avoid using wrappers. But only our own. > The wrapper is for say Tyrex distributed transactions, it should really be a > spec requirement that transactions are serializable (isn't that the case in > JINI?) In any case stop talking about the "the cost of a method invocation > in memory" when we are talking about distributed transactions, that price is > 1 in a million (if not less :) The wrapper would be for _any_ JTA implementation that is not hacked to avoid the wrappers. > |I agree that the extra conversion step in the transport is > |more ugly than just letting serialization/de-serialization > |do its work - but we should carefully balance this against > |the cost of the alternatives. > > it's not only ugly, it breaks pluggability. Currently, the TPCImporter and TPCFactory use a null TPC to denote "no transaction". It shouldn't be a problem to change the invoker to always use a null for the TPC on the wire if TPCImporter and TPCFactory have never been set. Otherwise (if you want to save the serializabled representation of null on the wire when no TM is plugged in), you are in effect changing to wire protocol when adding/removing the TM plugin. If no TM MBean has been started, looking up the TPCImporter and TPCFactory in JNDI should throw an exception. Catching this exception and ignoring it shouldn't be a problem. Or have I misunderstood something here? I am a bit worried if you are too blinded by the JRMP transport code (that i assume you are working on right now). I think this is the only object invocation transport that does not natively support transactions, and thus the only one where the TPCImporter and TPCFactory are really needed. Also, I think the JRMP transport is the only transport where (Java-)serialization of the transaction would make sense. IIOP, on the other hand, natively supports transaction propagation, and doesn't need TPCImporter and TPCFactory. Also, IIOP doesn't do (Java-)serialization, at least not for the propagated transaction. The cost of an extra method call due to the use of a wrapper may not sound of much, but the methods of Transaction are used quite a lot. Not just in the interceptors, but also from resources. And you want to incur this overhead everywhere in the server just to avoid a few lines of uglyness only needed for the JRMP transport? (Agreed, we could hack our own TM to avoid the overhead.) Best Regards, Ole Husgaard. |
From: marc f. <mar...@jb...> - 2002-03-02 20:20:03
|
|Do you want all instances of javax.transaction.Transaction |floating around the server to be instances of a JBoss-specific |extension of this interface that knows how to serialize itself? yes marcf |
From: marc f. <mar...@jb...> - 2002-03-02 20:38:26
|
|Do you want all instances of javax.transaction.Transaction |floating around the server to be instances of a JBoss-specific |extension of this interface that knows how to serialize itself? yes marcf |
From: Ole H. <os...@sp...> - 2002-03-03 20:18:29
|
Hi, marc fleury wrote: > |Do you want all instances of javax.transaction.Transaction > |floating around the server to be instances of a JBoss-specific > |extension of this interface that knows how to serialize itself? > > yes I still oppose this, for the reasons I already mentioned. Guess we better work to find a solution that we can both accept. Since you said nothing more about the pluggability issue, i assume we got this sorted out. Otherwise let me know. But since you are so strongly advocating wrapping up all calls to one of the central parts of the server, I guess that you have stronger arguments for it than just the code looking ugly in the MarshalledInvocation object. Please let me know your arguments. Note that the design with the TPCFactory and TPCImporter wasn't some quick hack. I gave it careful consideration. What I came up with is so common that it even has its own acronym in the transaction world: CRM (Communications Resource Manager): The entity that takes care of interfacing the core transaction service to the transports that need to support transaction propagation. I agree that changing the Transaction object to be Serializable would make the MarshalledInvocation implementation look more beautiful, but: 1) It would _only_ help the JRMP protocol invocation. 2) All calls to the transaction service from all other parts of JBoss will have to pass an extra layer, unless the transaction service has been hacked. 3) We have a bit extra load on the allocator and garbage collector, because multible copies of the same Transaction may float around the server. 3) Everybody would have to pay the penalty in 2), even if they do not use the JRMP protocol at all! I am willing to work with you to get your problem sorted out, but I am not willing to accept wrapping all calls to the Transaction and TransactionManager objects in an extra layer - unless you have some stronger arguments in support of it. Maybe, if you explicitly point out the problems you have with this in the current code, i can help you better. Please do. I think we can find a better solution. Best Regards, Ole Husgaard. |