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" 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. A?
??? 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.