Announcement Announcement Module
No announcement yet.
PROPAGATION_SUPPORTS vs. "no TX attributes" Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • PROPAGATION_SUPPORTS vs. "no TX attributes"

    Hi all

    We are working on a web-application which is based on Spring, Struts
    and Hibernate. The app. is modularized, with each module presenting a
    service layer for execution of business logic by the various Struts actions.
    The business layers are proxied for the purpose of applying transaction
    advice. The app. uses the OpenSessionInView filter, to ensure the
    existence of a primary Hibernate session throughout the request.

    All is well and good so far... there is however a question I just can't
    seem to find the answer to. Namely: What, exactly, is the difference
    between supplying _no_ transaction attributes for a service layer method,
    vs. specifying "PROPAGATION_SUPPORTS"?

    I've been perusing the concerned code, and from what i can tell, a
    method with no transaction attributes is simply ignored by the transaction
    interceptor, which makes sense... it's non-transactional, after all.

    I haven' had the time to really unravel the logic executed for
    PROPAGATION_SUPPORTS. but from the description of the mode:
    "participate in TX, if one exists, otherwise execute non-transactionally", i
    get the impression that it's essentially resulting in the same behavior that
    i'd get if i were to not specify TX attributes in the first place.

    More specifically:

    Given TX proxied objects "A" and "B", with A defining "foo()" and B "bar()"
    as methods. Assume foo() is declared to be transactional, let's say with
    PROPAGATION_REQUIRED, whereas bar() has no TX attributes specified.
    Futhermore, let it be the case, that foo() calls bar() while executing.

    Now, have a client execute foo()... foo() is transactional, so the transaction
    interceptor opens a TX. sooner or later, the thread enters bar(), for which
    no TX attributes have been specified. Happily ignored by the TX
    interceptor, bar() executes on foo()'s (Hibernate) TX.
    bar() returns, foo() ends, and the TX commits. conversely, if foo() had
    been non-transactional, then (obviously) bar() would have executed non-

    above behavior is how I understand PROPAGATION_SUPPORTS
    to operate... i.e., if foo() were declared as before, but bar() were provided
    with TX attribute "PROPAGATION_SUPPORTS", then wouldn't i get the
    same effect?

    what am i missing? i'd love for someone to help me out here...


  • #2
    The only difference between no transaction attribute at all and PROPAGATION_SUPPORTS is that the latter still defines a transactional scope that will be used for synchronization. So PROPAGATION_SUPPORTS won't create an underlying database transaction, but any resources used within its scope will nevertheless be synchronized: for example, a single JDBC Connection or Hibernate Session will be used for that scope. With no transaction attribute at all, no such synchronization will happen.

    In terms of practical use cases, I would recommend PROPAGATION_SUPPORTS for almost every operation that you don't want an explicit database transaction for (i.e. that you don't mark as PROPAGATION_REQUIRED). It's usually desirable to have synchronized shared resources for the scope of such facade operations, even without underlying database transaction (for example, for read operations on a single Hibernate Session).

    In general, it's recommendable to execute all database operations within transactions, even read-only operations: marked as PROPAGATION_REQUIRED,readOnly. However, if you encounter a scenario where read performance is hurt by the explicit transaction demarcation (caused by the database's internal processing or by the extra I/O between driver and database), consider PROPAGATION_SUPPORTS,readOnly.