`

SpringDM笔记22-Transactions Support With SpringDM

 
阅读更多

1. Spring’s transactional support

    Spring’s transactional support consists of two main parts for managing transactions on beans that

    are managed by the container:
    ■ Transactional synchronization —This manages resources used to handle transactions. This

    mechanism is directly integrated into Spring’s data access support and is based on a transactional

    context stored in a variable of type ThreadLocal.
    ■ Transaction demarcation —This allows you to apply transactions to application logic. Although an

    API is available, Spring also provides features to declaratively apply them to Spring-managed beans

    through AOP and annotations.

    The key abstraction for this support is the PlatformTransactionManager interface, which provides a

    contract for transaction demarcation. The following snippet shows the content of this interface:

   
    public interface PlatformTransactionManager {
          TransactionStatus getTransaction(TransactionDefinition definition);
          void commit(TransactionStatus status);
          void rollback(TransactionStatus status);
    }

 

    In the PlatformTransactionManager interface, the getTransaction method allows you to initialize

    and start a transaction. The commit method successfully finalizes a transaction; the rollback

    one cancels it.

   
    Implementations of this interface are provided for each data access implementation in Spring.

    These implementations are commonly based on factories for the corresponding technology

    (because they must be able to access resources to manage transactions), or, in the case of JTA,

    on the Java transaction manager.

  
    With respect to transaction propagation, Spring defaults to transactions being REQUIRED on

    beans, which allows application components to participate in the current transaction or to

    create it if it doesn’t exist. In addition, Spring introduces read-only transactions, which can help

    improve performance in ORM tools.

    You can configure transactions in Spring by following these steps:
    ■ Create and configure all your POJOs in the Spring container. They will correspond to abstractions

    for data access, DAO entities, and business services.
    ■ Configure a transaction manager bean, whose implementation depends on the underlying

    persistence technology.
    ■ Apply transactional behaviors to business services using either XML or transaction annotations.

    Transaction configuration using AOP and XML:

    <bean id="transactionManager" (...)>
         (...)
    </bean>
    <aop:config>
           <aop:advisor
                 pointcut="execution(* *..*ServiceImpl.*(..))"
                 advice-ref="txAdvice"/>

    </aop:config>

    <tx:advice id="txAdvice"  transaction-manager="transactionManager">
           <tx:attributes>
                 <tx:method name="add*"/>
                 <tx:method name="update*"/>
                 <tx:method name="delete*"/>
                 <tx:method name="*" read-only="true"/>
           </tx:attributes>
    </tx:advice>

    @Transactional
    public interface ContactsService {
          @Transactional(readOnly=true)
          List<Contact> getContacts();
          void addContact(Contact contact);
    }

    Another possibility is to use the Transactional annotation to specify transactional behavior

    directly in interfaces and classes. Information specified on interfaces is automatically
    used in corresponding implementations and can be overridden if necessary. The annotation

    can be specified both at the class level or method level. At the class level, it provides global 

    configuration for all methods, which can then be overridden if another configuration is required.

 

    Transactional annotation support isn’t activated by default and must be enabled through the

    annotation-driven element of Spring’s tx namespace, as shown in the following snippet:

    <bean id="transactionManager" (...)>
          (...)
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>

2. Using JPA transactions with Spring DM

    As emphasized in the previous section, the central abstraction of Spring’s transactional
    support is the PlatformTransactionManager. When using local transactions, the transaction

    manager implementation depends on the underlying data access technology, whereas

    for global transactions Spring provides a specific implementation that interacts with the

    underlying JTA transaction manager (which is usually hosted by an application server).

    We’ll describe here only the local transaction approach and use the annotation-driven

    method of configuring transactions.

    We can identify two use cases for configuring transaction management, depending on the

    organization of bundles within an application:

    ■ Services and DAOs are in the same component. In this case, Spring’s transaction support can

    be used as in regular Spring applications. The EntityManagerEntity entity, services, DAO, and

    Spring transaction manager are all located in the same Spring container.
    ■ Services and DAOs are in different components. In this case, services, the EntityManagerEntity

    entity, and the Spring transaction manager are located in different components. Because you

    need a transaction manager to apply transactions to services, this must be registered as an

    OSGi service. The service component is then able to reference and use it.

 

    In the first use case, bundles are autonomous(自治的), containing both services and DAO entities,

    and they embed their own transaction managers. Transactions are managed within these

    components,  and transactions are already applied to entities registered as OSGi services.

 

    In the use case where services and DAOs are separated, the Spring transaction manager can be

    provided as an OSGi service to a service component by the DAO component. In the service

    component, this service is used to apply transactions to services.

 

    The service for the Spring transaction manager is registered under the

    PlatformTransactionManager interface, which is the root interface for all transaction managers

    within Spring. That makes this service independent from the underlying data access technology.

 

    <bean id="entityManagerFactory" class="(...)">
          (...)
    </bean>
    <bean id="transactionManager"
          class="org.springframework.orm.jpa.JpaTransactionManager">
         
<property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <osgi:service ref="transactionManager"
          interface="org.springframework.transaction.PlatformTransactionManager"/>


    <osgi:reference id="transactionManager"
          interface="org.springframework.transaction.PlatformTransactionManager"/>
    <tx:annotation-driven transaction-manager="transactionManager"/>

 

    Import-Package: (...)
    javax.persistence.spi;version="1.0.0",
    org.aopalliance.aop;version="1.0",
    org.springframework.aop;version="3.0.0.M1",
    org.springframework.aop.framework;version="3.0.0.M1",
    org.springframework.transaction.annotation;version="3.0.0.M1 "

 

    We saw that Spring provides the Transactional annotation for describing transactional behavior.

    good practice consists of using this annotation on service interfaces. All the implementation classes

    will then directly benefit from the definition of transactional behavior at the interface level.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics