Você está na página 1de 37

Transaction Management with

the Spring Framework

Jürgen Höller
http://www.springframework.com
juergen@interface21.com
Agenda

 Introduction
 Transaction Demarcation
 Transaction Managers
 Data Access
 ORM Transactions
 Summary
Introduction (1)

 Spring is a general application framework


▫ addresses overall application architecture
• internal structure of an application
▫ focus on consistent programming model
• decoupling from concrete runtime environment
▫ supports any kind of Java application
• special support for J2EE environments
 Open source project on SourceForge
▫ founded by Rod Johnson & Jürgen Höller
▫ Apache license
Introduction (2)

 Foundation: core container


▫ Inversion of Control
• general lifecycle management
• for any kind of application components
▫ Dependency Injection
• wiring between application components
• instead service lookups
 Further foundation: AOP framework
▫ proxy-based AOP for POJOs
▫ flexible combination of interceptors
Introduction (3)
public class PetStoreImpl implements PetStoreFacade {
private OrderDao orderDao;
private ItemDao itemDao;
...
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
public void setItemDao(ItemDao itemDao) {
this.itemDao = itemDao;
}
...
public void insertOrder(Order order) {
this.orderDao.insertOrder(order);
this.itemDao.updateQuantity(order);
}
}
Introduction (4)
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"><value>...</value></property>
<property name="url"><value>...</value></property>
<property name="username"><value>...</value></property>
<property name="password"><value>...</value></property>
</bean>

<bean id="itemDao"
class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapItemDao">
<property name="dataSource"><ref bean="dataSource"/></property>
<property name="sqlMap"><ref bean="sqlMap"/></property>
</bean>

<bean id="petStore"
class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl">
<property name="orderDao"><ref bean="orderDao"/></property>
<property name="itemDao"><ref bean="itemDao"/></property>
</bean>
Introduction (5)

 Higher-level functionality on top


▫ transaction management
▫ data access support
▫ lightweight remoting, etc
 Subsystems can be used individually
▫ e.g. just Spring transaction management
▫ programmatically, in a plain library style
 Subsystems integrate nicely as a stack
▫ transaction management within core container
▫ declarative transactions via AOP
Introduction (6)

 Spotlight: transaction management


▫ separates transaction demarcation from the
concrete backend transaction manager
• consistent transaction demarcation style
• seamless support for both native transactions
and J2EE server transactions (JTA)
▫ flexible replacement for EJB CMT
 Relevant for many applications
▫ important part of overall application architecture
▫ in general, any kind of data access should operate
within a transaction
Transaction Demarcation (1)

 Transaction definition
▫ propagation behavior
• defaults to PROPAGATION_REQUIRED
▫ isolation level
• defaults to ISOLATION_DEFAULT
▫ read-only flag
• defaults to false
▫ transaction timeout
• defaults to none
▫ transaction name
• defaults to current method name (in declarative case)
Transaction Demarcation (2)

 Propagation behaviors
▫ supporting all EJB CMT propagation codes
• SUPPORTS
• REQUIRED
• REQUIRES_NEW
• NOT_SUPPORTED
• MANDATORY
• NEVER
▫ also supports NESTED
• if supported by underlying transaction manager
Transaction Demarcation (3)
 Programmatic demarcation a la JTA
▫ direct PlatformTransactionManager usage
▫ TransactionTemplate with TransactionCallback
 Declarative demarcation for arbitrary POJOs
▫ XML-based proxy definitions
• TransactionProxyFactoryBean definition per target bean
▫ auto-proxy creator mechanism
• centralized XML transaction metadata for multiple beans
• instead of specific transaction proxy definitions
▫ transaction metadata in Java source code
• Jakarta Commons Attributes
• J2SE 5.0 annotations
Transaction Demarcation (4)

 TransactionTemplate usage example

public class PetStoreImpl implements PetStoreFacade {

private PlatformTransactionManager ptm;

public void setTransactionManager(PlatformTransactionManager ptm) {


this.ptm = ptm;
}

public void insertOrder(Order order) {


TransactionTemplate tt = new TransactionTemplate(this.ptm);
tt.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus ts) {
// perform some transactional operations
...
return null;
}
});
}
}
Transaction Demarcation (5)
<bean id="petStoreTarget"
class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl">
<property name="orderDao"><ref bean="orderDao"/></property>
<property name="itemDao"><ref bean="itemDao"/></property>
</bean>

<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager"/>

<bean id="petStore"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="target"><ref bean="petStoreTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
Transaction Demarcation (6)

 Example for J2SE 5.0 annotations

public class PetStoreImpl implements PetStoreFacade {

private OrderDao orderDao;


private ItemDao itemDao;
...

public void setOrderDao(OrderDao orderDao) {


this.orderDao = orderDao;
}
public void setItemDao(ItemDao itemDao) {
this.itemDao = itemDao;
}
...

@Transactional
public void insertOrder(Order order) {
this.orderDao.insertOrder(order);
this.itemDao.updateQuantity(order);
}
}
Transaction Managers (1)
 Native transaction managers
▫ JDBC: DataSourceTransactionManager
▫ Hibernate: HibernateTransactionManager
▫ TopLink: TopLinkTransactionManager
▫ JDO: JdoTransactionManager
▫ etc
 Native strategies work in any environment
▫ but only against a single database!
• no distributed transaction coordination
▫ leverage full power of underlying resource
• isolation levels, savepoints, etc
Transaction Managers (2)
 JTA-based transaction coordinator
▫ Spring's JtaTransactionManager adapter
▫ using the Java Transaction API to talk to an
external transaction coordinator
• typically using the standard XA protocol to coordinate
heterogeneous transactional resources
 Typically: J2EE server's JTA subsystem
▫ delegates to JTA UserTransaction
• a standard J2EE component, available from JNDI
▫ optionally accesses JTA TransactionManager
• server-specific, for transaction suspension
• automatically detected on most J2EE servers
Transaction Managers (3)
 Special support for extended JTA
▫ on specific J2EE servers
▫ through special JtaTransactionManager subclasses
 WebLogicJtaTransactionManager
▫ support for WebLogic's JTA extensions
• transaction names for WebLogic's transaction monitor
(part of the administration console)
• enforced transaction resume in all cases
• per-transaction isolation levels
▫ runs on WebLogic 7.0+
 Support for other extensions on the roadmap
Transaction Managers (4)
 Transaction manager is a deployment choice
▫ application code is completely decoupled from
concrete transaction infrastructure
▫ application specifies desired transaction semantics;
transaction manager provides them at runtime
 Seamless switching between native
transactions and JTA transactions
▫ between non-J2EE and J2EE environments
• e.g.: run integration tests with native transactions
• e.g.: run with J2EE transactions in production
▫ or even run with native transactions in production
• if all you need is transactions for a single database
Transaction Managers (5)
 Typical scenarios for JDBC
▫ standalone application / integration tests
• native JDBC DataSourceTransactionManager
▫ J2EE web application running on Tomcat
• native JDBC DataSourceTransactionManager
▫ J2EE web application running on WebLogic
• J2EE transactions via standard JtaTransactionManager
• or WebLogicJtaTransactionManager for advanced support
 Could also use third-party JTA provider
▫ for standalone application or Tomcat
▫ for example: ObjectWeb JOTM
• or standalone Geronimo transaction manager
Data Access (1)
 Data access objects need to access
transactional resources
▫ as seamlessly as possible
• easy access to scoped transactional resource
▫ automatically participate in transactions
• ideally: run non-transactionally else
 JDBC: talk to transactional DataSource
▫ returns active Connection for current transaction
▫ for example: J2EE server DataSource
• fetched from JNDI via JndiObjectFactoryBean
▫ or transactional DataSource proxy
• for local connection pool
Data Access (2)
 Two different approaches
▫ use native resource API only
▫ or use Spring's DAO implementation helpers
 Native JDBC API
▫ talk to provided transactional DataSource
 Native Hibernate API
▫ use SessionFactory.getCurrentSession() on provided
SessionFactory
 Native TopLink API
▫ use Session.getActiveUnitOfWork() on
provided Session
Data Access (3)
 Spring provides DAO implementation helpers
▫ convenient template classes
▫ implicit access to resources
▫ many operations become one-liners
▫ no try/catch blocks anymore
 Pre-built integration classes for different APIs
▫ JDBC: JdbcTemplate
▫ Hibernate: HibernateTemplate
▫ TopLink: TopLinkTemplate
▫ JDO: JdoTemplate
▫ etc
Data Access (4)

 Further benefit: common DAO exceptions


▫ well-defined exceptions at DAO interface level
▫ do not couple caller to DAO implementation strategy
• even if specific exception conditions need to be handled
 Spring's DataAccessException hierarchy
▫ independent of JDBC, Hibernate, TopLink, JDO, etc
▫ unchecked (= a RuntimeException), as most data
access failures are not recoverable
▫ subclasses like OptimisticLockingFailureException
and DataAccessResourceFailureException
Data Access (5)

 Example for a DAO based on Spring's


JdbcTemplate

public class ExampleDao extends JdbcDaoSupport {

public void clearDatabase() throws DataAccessException {


getJdbcTemplate().update("DELETE FROM imagedb");
}

public void deleteImage(int imageId) throws DataAccessException {


getJdbcTemplate().update("DELETE FROM imagedb WHERE id=?",
new Object[] {new Integer(imageId)});
}

public int getNrOfImages() throws DataAccessException {


return getJdbcTemplate().queryForInt(
"SELECT COUNT(*) FROM imagedb");
}
}
Data Access (6)

 Example for a DAO based on Spring's


HibernateTemplate

public class ExampleHibernateDao extends HibernateDaoSupport {

public List getVets() throws DataAccessException {


return getHibernateTemplate().find(
"from Vet vet order by vet.lastName, vet.firstName");
}

public List findOwners(String lastName) throws DataAccessException {


return getHibernateTemplate().find(
"from Owner owner where owner.lastName like ?", lastName + "%");
}

public Owner loadOwner(int id) throws DataAccessException {


return getHibernateTemplate().load(Owner.class, new Integer(id));
}
}
Data Access (7)
 Alternative: a plain Hibernate DAO
public class ExampleHibernateDao {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sf) {
this.sessionFactory = sf;
}
public List getVets() {
return this.sessionFactory.getCurrentSession().
createQuery("from Vet vet order by vet.lastName, vet.firstName").
list();
}
public Owner loadOwner(int id) {
return this.sessionFactory.getCurrentSession().
load(Owner.class, new Integer(id));
}
}
ORM Transactions (1)

 Object/Relational Mapping tools require


proper transaction integration
▫ synchronization with transactions
• cache callbacks on commit / rollback
• required for transactional cache handling
▫ scoping of ORM resources
• one Hibernate Session per transaction
• one TopLink UnitOfWork per transaction
• one JDO PersistenceManager per transaction
• required for proper transaction isolation
ORM Transactions (2)

 ORM tools usually support two different


transaction modes
▫ native transactions through ORM API
▫ participating in global JTA transactions
▫ -> different programming model!
 Spring supports consistent transaction
demarcation across all environments
▫ native transactions or global JTA
▫ same transaction demarcation
▫ same DAO implementation model
ORM Transactions (3)

 Spring provides pre-built integration for


all major ORM providers
▫ Hibernate 2.1 / 3.x
▫ TopLink 9.0.4 / 10.1.3
▫ JDO 1.0 / 2.0
▫ Apache OJB 1.0
 Set of integration classes per strategy
▫ factories for ORM resources
▫ native transaction managers
▫ DAO implementation helpers
ORM Transactions (4)

 Example: Hibernate
▫ Spring's LocalSessionFactoryBean
• setup of Hibernate SessionFactory
▫ Spring's HibernateTransactionManager
• native transactions against single database
▫ Spring's HibernateTemplate
• implicit management of Hibernate Sessions
• or use SessionFactory.getCurrentSession()
▫ Spring's OpenSessionInViewFilter
• seamless lazy loading during view rendering
ORM Transactions (5)

 Example: TopLink
▫ Spring's LocalSessionFactoryBean
• setup of TopLink SessionFactory /
TopLink master Session
▫ Spring's TopLinkTransactionManager
• native transactions against single database
▫ Spring's TopLinkTemplate
• implicit management of TopLink Session /
UnitOfWork
• or use Session.getActiveSession() /
Session.getActiveUnitOfWork()
ORM Transactions (6)

 Newest kid on the block: JPA


▫ Java Persistence API 1.0
• aka "EJB3 persistence" / "JSR-220 persistence"
• part of the forthcoming J2EE 5.0
▫ optimized for application servers
• explicit, strong integration with J2EE transactions
• but also usable in a standalone fashion
 Spring will support JPA persistence
▫ as further ORM strategy, analogous to JDO
▫ use Spring's transaction management
with JPA-based DAOs
ORM Transactions (7)
 Example for a plain JPA DAO, using the
"shared EntityManager proxy" model
public class ExampleJpaDao {
private EntityManager entityManager;
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public List getVets() {
return this.entityManager.createQuery(
"from Vet vet order by vet.lastName, vet.firstName").
getResultList();
}
public Owner loadOwner(int id) {
return this.entityManager.find(Owner.class, new Integer(id));
}
}
Summary (1)

 Spring provides generic transaction


management for any kind of Java application
▫ consistent programming model
▫ consistent transaction demarcation
▫ seamless switching between different transaction
managers
 Declarative transaction demarcation
▫ XML-based proxy definitions
▫ JDK 5.0 annotations
▫ alternative: programmatic demarcation
Summary (2)

 Seamless switching between native


transactions and JTA transactions
▫ consistent programming model across different
deployment scenarios
▫ leverage J2EE server when available,
while still being able to run outside of J2EE
 Full declarative transactions even on Tomcat!
▫ on the other end of the spectrum:
WebLogic JTA extensions supported as well
▫ choose deployment environment according to your
service needs (scaling both up and down)
Summary (3)

 Explicit support for ORM tools


▫ transaction synchronization
• scoping of ORM resources
▫ consistent transaction demarcation across
native transactions and JTA transactions
• with consistent ORM semantics
 All major ORM providers supported
▫ Hibernate, TopLink, JDO, JPA, etc
▫ integration comes out-of-the-box!
• maintained by Spring team
http://www.springframework.org

http://www.springframework.com

Você também pode gostar