Discussions

News: Colin Sampaleanu on Spring 1.2's Transaction Annotations

  1. Colin Sampaleanu describes Spring 1.2's Java 5-based transaction annotations in this blog entry. Spring's transaction-wrapping capability is considered one of its best comparison points against the use of Enterprise Java Beans.
    Used in bare form, [@Transactional] specifies that an interface, class, or method must be transactional. Default transaction semantics are read/write, PROPAGATION_REQUIRED, ISOLATION_DEFAULT, TIMEOUT_DEFAULT, with rollback on a RuntimeException, but not Exception.
    Other rollback signals (i.e., Exception) can be added to the annotation as well.

    He walks through the actual configuration, showing the XML configuration of transactions, and then he shows how AOP can be used to ensure the transactional notation is applied.

    His summary:
    I hope that I’ve gotten you at least a little bit eager to try using the transaction Annotations in your Spring-based applications. My feeling is that as more and more code starts running in a Java 5+ environment, and Java 5+ dependencies become acceptable, using Annotations for transaction demarcation will be the prefered mechanism. They’re certainly a great way to reduce boilerplate XML, and move the information about what needs to be wrapped transactionally much closer to the actual code being wrapped, without any significant negatives.

    Threaded Messages (19)

  2. That's a good breakdown of how to use annotations. I still prefer the XML declaration so that you can leverage filters and do something like the following:

    <prop key="save*">PROPAGATION_REQUIRED</prop>
    <prop key="delete*">PROPAGATION_REQUIRED</prop>
    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>

    By using this approach, you don't have to annotate or declare the transaction strategy for every single method and the code is easier to maintain.
  3. That's a good breakdown of how to use annotations. I still prefer the XML declaration so that you can leverage filters and do something like the following:<prop key="save*">PROPAGATION_REQUIRED</prop><prop key="delete*">PROPAGATION_REQUIRED</prop><prop key="find*">PROPAGATION_REQUIRED,readOnly</prop><prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>By using this approach, you don't have to annotate or declare the transaction strategy for every single method and the code is easier to maintain.

    I totally agree with you. I never understood all the hype around transaction annotations. The method that you describe (and that I personally use) is much more interesting.

    Pedro Costa
  4. Annotations are useless![ Go to top ]

    Annotations are (most of the time) completely useless and I can't understand why there is such a nonsense hype around them.

    -Annotations "need" an external definition file.
    With annotations I still have to put somewhere (lets guess ohh yes yet another XML file) the info about which components I have applied annotations (unless you want to walk through million of components to discover which one is annotated at deployment time or "better" a runtime ).
    Why should I use them if I could put the same info in an XML file?

    -Annotations are completely unmanageable.
    How can you manage thousand (or more) of annotated components in your enterprise application ?
    If a requirement changes
    should I go through all of them to modify them accordinely ?
    How do I know which components are effected by that change ?
    What a nightmare.

    -Annotations are static.
    If I deploy a business component with Transaction_Required and later I deploy the same component
    within another context (another prod env) with different tx requirements I am screwed up and I have to modify the code. Thats really great. What an improvement....

    -Annotations are not reusable.
    Metadata should be reusable and be able to apply it to more than a single class. Talking about OO and reusability but they fail so poorly on this.....

    This is only the top of the iceberg of a bigger problem...
    how pathetic the IT market has become.
  5. Annotations are useless![ Go to top ]

    I think annotations are probably better for targeted, coarse-grained operations (such as, deploying a class as a web service). In particular, if it is important for someone who is reading the code to know unambiguously that a cross-cutting concern is being applied to a class, annotations may make sense.

    I agree that for a very generalized operation like transaction management, the XML configuration is more appealing. However, once EJB3 becomes widely adopted, there will be a certain class of users that expect to be able to demarcate transactions through attributes.
    With annotations I still have to put somewhere (lets guess ohh yes yet another XML file) the info about which components I have applied annotations (unless you want to walk through million of components to discover which one is annotated at deployment time or "better" a runtime ).

    I don't really think that's accurate. The Spring config allows you to specify the single annotation, not each of the annotated classes. And the "walk through... components" phase you describe is just the standard bean post processor step that occurs during any Spring application configuration. The additional overhead of checking for the existence of the attribute is minimal (certainly much less than actually proxying the transactional support), and I doubt that even the largest application has "millions" of Spring services.
  6. You missed one...[ Go to top ]

    One of the best features of using XML config files is that you can validate them against a DTD or XSD. You can't do this with annotations.

    I disagree that annotations are useless however, I think 'misused' and 'over used' would be a better description.
  7. Sorry. Had a brain fart. Was talking about XDOCLET!
  8. Annotations are useless![ Go to top ]

    Annotations are (most of the time) completely useless

    XDoclet fans would beg to differ and annotations are 100 times better than XDoclet.
    -Annotations "need" an external definition file.With annotations I still have to put somewhere (lets guess ohh yes yet another XML file) the info about which components I have applied annotations (unless you want to walk through million of components to discover which one is annotated at deployment time or "better" a runtime ).

    From what I gather from the Spring article here, that if you use their AOP framework, you do not have to specify which bean's have annotations individually. This is the same as other AOP frameworks like JBoss AOP and AspectJ that allow you to trigger behavior from an application of an annotation.

    Why should I use them if I could put the same info in an XML file?

    Awhile ago, I blogged about this, but it boils down to: If the metadata you are applying effects the design of your class, then you should probably use an annotation.
    -Annotations are completely unmanageable. How can you manage thousand (or more) of annotated components in your enterprise application ?

    Can't speak for other IDE's, but IntelliJ has great support for annotations. You can search for their usages just like you would any other construct. You can search for annotation attribute usage as well. With XML, you're stuck with a plain string search.
    If a requirement changes should I go through all of them to modify them accordinely ?How do I know which components are effected by that change ?What a nightmare.

    You would have the same problem with XML, except, when you use annotations with an IDE, the IDE can do most of the work for you.
    -Annotations are static. If I deploy a business component with Transaction_Required and later I deploy the same componentwithin another context (another prod env) with different tx requirements I am screwed up and I have to modify the code. Thats really great. What an improvement....

    Nobody said you have to use annotations for everything...Again, read me thoughts on this linked above.

    But, many framework out there support support annotation overriding. EJB3 allows you to override any EJB3 based annotations via the XML DD. JBoss AOP has a more generic override facility. I'm sure Spring has similar annotation override facilities?

    -Annotations are not reusable. Metadata should be reusable and be able to apply it to more than a single class. Talking about OO and reusability but they fail so poorly on this.....This is only the top of the iceberg of a bigger problem...how pathetic the IT market has become.

    Please elaborate on how Annotations are not reusable.
    * AOP frameworks like JBoss AOP(and AspectJ?) allow you to apply annotations through pointcut expressions. This allows you to apply metadata to a whole group of classes instead of just one-by-one.
    * Did you know that Annotations are java interfaces and that you can implement them in a concrete Java class? In JBoss EJB3, we use annotations as our meta-model.

    If annotations don't work for you, then don't use them. The popularity of XDoclet shows that people want to embed their metadata within their code.

    Bill
  9. Annotations are useless![ Go to top ]

    If annotations don't work for you, then don't use them. The popularity of XDoclet shows that people want to embed their metadata within their code.

    But is that really all that wise? I'd think some metadata belongs in code, but a lot of other metadata doesn't.
  10. Annotations are useless![ Go to top ]

    If annotations don't work for you, then don't use them. The popularity of XDoclet shows that people want to embed their metadata within their code.
    But is that really all that wise? I'd think some metadata belongs in code, but a lot of other metadata doesn't.

    That's not what I said. Reread my post and read my opinion on annotations.

    BIll
  11. Annotations are useless![ Go to top ]

    EJB3 allows you to override any EJB3 based annotations via the XML DD. JBoss AOP has a more generic override facility. I'm sure Spring has similar annotation override facilities?

    Well, Spring is not quite as annotation-happy as EJB3. We don't consider annotations as the default, with an XML file overriding annotations for special cases only. We rather consider annotations as just another way to implement a specific configuration interface (such as Spring's TransactionAttributeSource), with the respective configuration interface playing the central role. This has worked very well for us so far.

    With Spring, you can choose to apply annotations on a specific basis. For example, you can limit auto-proxying to certain beans (through using BeanNameAutoProxyCreator instead of DefaultAdvisorAutoProxyCreator): this would only read and apply the Transactional annotation from specific beans. Other beans in the same context could be proxied through Spring TransactionProxyFactoryBean definitions in XML, leveraging the extended configuration options there.

    Juergen
  12. Annotations are useless![ Go to top ]

    Annotations are (most of the time) completely useless
    XDoclet fans would beg to differ and annotations are 100 times better than XDoclet.

    Well it is not a good reason to use one technology because it is better than another one. Anyway XDoclet is an annotation concept implemented as workaround. So your point makes no sense here. I do use a given technology because it makes sense and not because it is better than another technology that might not have sense at all.
    -Annotations "need" an external definition file.With annotations I still have to put somewhere (lets guess ohh yes yet another XML file) the info about which components I have applied annotations (unless you want to walk through million of components to discover which one is annotated at deployment time or "better" a runtime ).
    From what I gather from the Spring article here, that if you use their AOP framework, you do not have to specify which bean's have annotations individually. This is the same as other AOP frameworks like JBoss AOP and AspectJ that allow you to trigger behavior from an application of an annotation.

    Yes yes everybody know we can use AOP to inject stuff trasparently but you missed the point. You need an XML with AOP anyway, right ? So what is your point ? Instead of using annotations + xml you are suggesting to use annotation + AOP + xml. As you can see xml is still there....

    Why should I use them if I could put the same info in an XML file?
    Awhile ago, I blogged about this, but it boils down to: If the metadata you are applying effects the design of your class, then you should probably use an annotation.

    Well class evolves in my world, so does the metadata. Can you really say the metadata will always effect only one single class ? I can't
    -Annotations are completely unmanageable. How can you manage thousand (or more) of annotated components in your enterprise application ?
    Can't speak for other IDE's, but IntelliJ has great support for annotations. You can search for their usages just like you would any other construct. You can search for annotation attribute usage as well. With XML, you're stuck with a plain string search.

    Yes indeed I am stuck with a single point of entry. Thats my point.
    If a requirement changes should I go through all of them to modify them accordinely ?How do I know which components are effected by that change ?What a nightmare.
    You would have the same problem with XML, except, when you use annotations with an IDE, the IDE can do most of the work for you.

    See above, single entry point! Thats the key.
    ..and btw I might not want to modify the metadata of my components with an IDE. How can you batch that process with IDE ?
    -Annotations are static. If I deploy a business component with Transaction_Required and later I deploy the same componentwithin another context (another prod env) with different tx requirements I am screwed up and I have to modify the code. Thats really great. What an improvement....
    Nobody said you have to use annotations for everything...Again, read me thoughts on this linked above.But, many framework out there support support annotation overriding. EJB3 allows you to override any EJB3 based annotations via the XML DD. JBoss AOP has a more generic override facility. I'm sure Spring has similar annotation override facilities?

    Again why should I put n tech layers of indirections to correct a fondamental problem of a given technology ?
    We all know we can do pretty much everything with tech workarounds but does it make any sense ?
    Yes we can use AOP again and override them and again you still need XML. ;-)

    -Annotations are not reusable. Metadata should be reusable and be able to apply it to more than a single class. Talking about OO and reusability but they fail so poorly on this.....This is only the top of the iceberg of a bigger problem...how pathetic the IT market has become.
    Please elaborate on how Annotations are not reusable. * AOP frameworks like JBoss AOP(and AspectJ?) allow you to apply annotations through pointcut expressions. This allows you to apply metadata to a whole group of classes instead of just one-by-one.* Did you know that Annotations are java interfaces and that you can implement them in a concrete Java class? In JBoss EJB3, we use annotations as our meta-model.If annotations don't work for you, then don't use them. The popularity of XDoclet shows that people want to embed their metadata within their code.Bill


    Again you need AOP and XML.
    Can you answer this question...
    WHY do not we just use AOP and XML to achieve the SAME result?

    BTW This is a critic on annotation and not on Spring.
    As a matter of fact they provide both annotation and XML and definetely I prefer the XML way.
  13. Annotations are useless![ Go to top ]

    sorry I messed up with blockquote
    Annotations are (most of the time) completely useless
    XDoclet fans would beg to differ and annotations are 100 times better than XDoclet.

    Well it is not a good reason to use one technology because it is better than another one. Anyway XDoclet is an annotation concept implemented as workaround. So your point makes no sense here. I do use a given technology because it makes sense and not because it is better than another technology that might not have sense at all.
    -Annotations "need" an external definition file.With annotations I still have to put somewhere (lets guess ohh yes yet another XML file) the info about which components I have applied annotations (unless you want to walk through million of components to discover which one is annotated at deployment time or "better" a runtime ).
    From what I gather from the Spring article here, that if you use their AOP framework, you do not have to specify which bean's have annotations individually. This is the same as other AOP frameworks like JBoss AOP and AspectJ that allow you to trigger behavior from an application of an annotation.

    Yes yes everybody know we can use AOP to inject stuff trasparently but you missed the point. You need an XML with AOP anyway, right ? So what is your point ? Instead of using annotations + xml you are suggesting to use annotation + AOP + xml. As you can see xml is still there....
    Why should I use them if I could put the same info in an XML file?
    Awhile ago, I blogged about this, but it boils down to: If the metadata you are applying effects the design of your class, then you should probably use an annotation.

    Well class evolves in my world, so does the metadata. Can you really say the metadata will always effect only one single class ? I can't
    -Annotations are completely unmanageable. How can you manage thousand (or more) of annotated components in your enterprise application ?
    Can't speak for other IDE's, but IntelliJ has great support for annotations. You can search for their usages just like you would any other construct. You can search for annotation attribute usage as well. With XML, you're stuck with a plain string search.

    Yes indeed I am stuck with a single point of entry. Thats my point.
    If a requirement changes should I go through all of them to modify them accordinely ?How do I know which components are effected by that change ?What a nightmare.
    You would have the same problem with XML, except, when you use annotations with an IDE, the IDE can do most of the work for you.

    See above, single entry point! Thats the key.
    ..and btw I might not want to modify the metadata of my components with an IDE. How can you batch that process with IDE ?
    -Annotations are static. If I deploy a business component with Transaction_Required and later I deploy the same componentwithin another context (another prod env) with different tx requirements I am screwed up and I have to modify the code. Thats really great. What an improvement....
    Nobody said you have to use annotations for everything...Again, read me thoughts on this linked above.But, many framework out there support support annotation overriding. EJB3 allows you to override any EJB3 based annotations via the XML DD. JBoss AOP has a more generic override facility. I'm sure Spring has similar annotation override facilities?

    Again why should I put n tech layers of indirections to correct a fondamental problem of a given technology ?
    We all know we can do pretty much everything with tech workarounds but does it make any sense ?
    Yes we can use AOP again and override them and again you still need XML. ;-)
    -Annotations are not reusable. Metadata should be reusable and be able to apply it to more than a single class. Talking about OO and reusability but they fail so poorly on this.....This is only the top of the iceberg of a bigger problem...how pathetic the IT market has become.
    Please elaborate on how Annotations are not reusable. * AOP frameworks like JBoss AOP(and AspectJ?) allow you to apply annotations through pointcut expressions. This allows you to apply metadata to a whole group of classes instead of just one-by-one.* Did you know that Annotations are java interfaces and that you can implement them in a concrete Java class? In JBoss EJB3, we use annotations as our meta-model.If annotations don't work for you, then don't use them. The popularity of XDoclet shows that people want to embed their metadata within their code.Bill


    Again you need AOP and XML.
    Can you answer this question...
    WHY do not we just use AOP and XML to achieve the SAME result?

    BTW This is a critic on annotation and not on Spring.
    As a matter of fact they provide both annotation and XML and definetely I prefer the XML way.
  14. Annotations are useless![ Go to top ]

    Annotations are (most of the time) completely useless and I can't understand why there is such a nonsense hype around them..

    Such "metadata" needs to be captured somewhere.

    We all seek the paradigm of "put associated information in one and only one place for superior clarity and maintainability." However, whether that means putting it all in XML files, put it all in annotations, or a combination of both is an evolving science and a matter of personal style.

    For now, having BOTH solutions makes real good sense as we, as a software community, figure out how to achieve clearer, cleaner and more readable software.

    Steve Punte
    JXReports
  15. That's a good breakdown of how to use annotations. I still prefer the XML declaration so that you can leverage filters and do something like the following:<prop key="save*">PROPAGATION_REQUIRED</prop><prop key="delete*">PROPAGATION_REQUIRED</prop><prop key="find*">PROPAGATION_REQUIRED,readOnly</prop><prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>By using this approach, you don't have to annotate or declare the transaction strategy for every single method and the code is easier to maintain.

    Nothing says it has to be one or the other... I personally do both. I have these kind of mappings for my DAOs to ensure that they're getting called with a transaction, and I also use annotations to declare the transactionality of business service methods.
  16. specify default on Class[ Go to top ]

    By using this approach, you don't have to annotate or declare the transaction strategy for every single method and the code is easier to maintain.

    The common implementation pattern is to specify the default value for an annotation on the class, then override it per method as needed.

    @Stateless
    @TransactionAttribute(REQUIRED)
    public class BusinessLogicBean implements BusinessLogic {

       public void method1() { /* inherits REQUIRED */ }

       @TransactionAttribute(NOT_SUPPORTED)
       public void getSomething() { /* override class default */ }
    }

    Personally, I don't like the wildcard approach is it is very easy to apply behavior you don't want to apply. In general, I don't think it is good usage to apply behavior with a wildcard.

    Bill
  17. I actually like transaction attributes in XML as well - in concise XML, that is. In combination with the parent/child bean definition feature of Spring's core container, XML-based annotations can be a breeze - especially if your method naming patterns are somewhat consistent throughtout your app (for example: "get*" always being read-only, etc).

    Concrete XML definitions for transactional proxies can be as concise as:

    <bean id="myService" parent="baseTransactionProxy">
      <property name="target" ref="myServiceTarget"/>
    </bean>

    <bean id="myOtherService" parent="baseTransactionProxy">
      <property name="target" ref="myOtherServiceTarget"/>
    </bean>

    With the "transactionManager" reference and the "transactionAttributes" defined in the base bean definition "baseTransactionProxy" - only once per app (or module)!

    <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
      <property name="transactionManager" ref="transactionManager"/>
      <property name="transactionAttributes">
        <props>
          <prop key="get*">PROPAGATION_REQUIRED,readOnly,timeout_5</prop>
          <prop key="find*">PROPAGATION_REQUIRED,readOnly,timeout_10</prop>
          <prop key="*">PROPAGATION_REQUIRED,timeout_20</prop>
        </props>
      </property>
    </bean>

    The advantage of explicit XML-based transaction attributes, in particular of centrally defined ones like above, is that you can adapt specific timeout values etc without changing and recompiling your Java code. You can even use Spring's placeholder mechanism there, for example: ${readTimeout} with the actual timeout value defined in a properties file.

    Of course, Spring leaves the choice up to the application developer: If you prefer transaction annotations in your Java source code, use them - as Colin has shown, this is available right now. If you prefer an XML-based variant, choose one instead (there's actually a variety). We will continue to support both as first-class options.

    Juergen

    -----
    Juergen Hoeller
    Interface21 - Spring Services from the Source http://www.springframework.com
  18. exception handling incomplete[ Go to top ]

    I think your exception handling is incomplete. I much prefer the EJB3 way of defining exceptions that rollback transactions automatically.

    @ApplicationException(rollback=true)
    public class MyCheckedException extends Exception{}

    ---

    @Stateless
    public BusinessBean implements BusinessInterface {

       public void method1() throws MyCheckedException {...{

    }

    ---

    I do agree though that the ability to specify the rollback exceptions on the business method is needed and important. I will be urging the EJB3 EG to support that semantic. That being said, I still think that the EJB3 way is a much *cleaner* solution.

    Also, I think you should be able to define the rollback exceptions as a default for the entire class, for example:

    @ApplicationExceptions({
       @ApplicationException(exceptionClass=MyCheckedException.class, rollback=true),
       @ApplicationException(exceptionClass=java.sql.SQLException.class, rollback=true)
    })
    public class MyBean {...}
  19. exception handling incomplete[ Go to top ]

    I think your exception handling is incomplete. I much prefer the EJB3 way of defining exceptions that rollback transactions automatically. @ApplicationException(rollback=true)public class MyCheckedException extends Exception{}---@Statelesspublic BusinessBean implements BusinessInterface {&nbsp;&nbsp;&nbsp;public void method1() throws MyCheckedException {...{}

    Actually, I consider this form to be of very dubious value, and a misuse of Annotations. You have an exception class, that will potentially be thrown by methods in multiple business services, yet you are putting the information about the fact that you want a rollback (or presumably non-rollback, I haven't verified whether the last version of the EJB 3 spec allows you to set non-rollbacks for RuntimeExceptions) in the exception class itself. This is completely the wrong place to put this information, as the exception should know nothing about the exact semantics of its use. It may be completely appropriate for the exception to cause a rollback in one service, and not in another. This information needs to be either as an Annotation in the service (interface or impl) itself, or somewhere external to both, such as an XML config file.
    ---I do agree though that the ability to specify the rollback exceptions on the business method is needed and important. I will be urging the EJB3 EG to support that semantic. That being said, I still think that the EJB3 way is a much *cleaner* solution.Also, I think you should be able to define the rollback exceptions as a default for the entire class, for example:@ApplicationExceptions({&nbsp;&nbsp;&nbsp;@ApplicationException(exceptionClass=MyCheckedException.class, rollback=true),&nbsp;&nbsp;&nbsp;@ApplicationException(exceptionClass=java.sql.SQLException.class, rollback=true)})public class MyBean {...}

    You can in Spring right now apply rollback/no-rollback rules with a default value for the entire interface or class, as part of a 'Transactional' Annotation on an interface or class. Keep in mind the Annotation can set the Tx propagation setting to PROPAGATION_SUPPORTS. This means by default, transactions will not be created, only joined if they exist. So this is in usage exactly identical to the use of EJB 3's @ApplicationExceptions (and I would have hoped that you would have seen this, it's fairly obvious, which is why I didn't mention it anywhere, but I'll make sure to update my original article).

    We've talked about adding another Annotation like @ApplicationExceptions, and it may still happen, but I really think it confuses the picture. We're talking about exceptions rolling back or not rolling back _transactions_. It's not like the annotation would have any effect wihout transactions in place. So why would it not be the preferred place to specify this as part of a default Transactional Annotation for the interface or class as in the Spring approach?

    Regards,
    Colin
  20. On reflection, using Spring's Transactional Annotation at the interface or class level, with propagation set to PROPAGATION_REQUIRED would not always have the same semantics as Bill's @ApplicationExceptions example.

    In the Spring case, any class methods without the annotation would join any existing transaction and the interface or class level rule would affect rollback, but if a method were to specify its own Transactional Annotation that would override everything, including the rollback rules. The Annotations are intentionally not additive.

    The @ApplicationExceptions approach presumably implies that the exception handling semantics are unchanged regardless of particular transaction annotations on the individual methods. This is all hypothetical (to me anyway, not being privy to the non-public stuff in the EJB spec), as that Annotation doesn't exist in the PR draft.

    In any case, as I said, it's something that we've considered and is pretty easy to implement. Based on thinking about this use case again just now I'm more amenable to adding such an annotation, as I'm always interested in reducing boilerplate config.