Spring中事务管理浅谈
Spring中事务管理浅谈
Spring中对事务的声明式管理
拿一个XML举例
[html]- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
- 事务管理目标Service
- <bean id="fooService" class="x.y.service.DefaultFooService"/>
- 切面配置,配置了切入点是执行FooService下的所有方法 和 切入点调用的通知器为txAdvice
- <aop:config>
- <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>
- <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
- </aop:config>
- 该通知器的具体配置,所使用的事务管理器,所配置的事务规则
- <tx:advice id="txAdvice" transaction-manager="txManager">
- <!-- the transactional semantics... -->
- <tx:attributes>
- <!-- all methods starting with 'get' are read-only -->
- <tx:method name="get*" read-only="true"/>
- <!-- other methods use the default transaction settings (see below) -->
- <tx:method name="*"/>
- </tx:attributes>
- </tx:advice>
- 所选用的事务管理器,和作为启动参数塞入的dataSource
- <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="dataSource"/>
- </bean>
- 连接数据库的dataSource
- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
- <property name="driverClassName" value="Oracle.jdbc.driver.OracleDriver"/>
- <property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/>
- <property name="username" value="scott"/>
- <property name="password" value="tiger"/>
- </bean>
- </beans>
Spring中对事务管理的底层实现
以上的方法,选用了Spring本身自带的JDBC的事务控制器做处理。
相关代码集中在DataSourceTransactionManager中
比如,事务的取得并且将取得的事务捆绑进当前线程中
[java]- @Override
- protected Object doGetTransaction() {
- DataSourceTransactionObject txObject = new DataSourceTransactionObject();
- txObject.setSavepointAllowed(isNestedTransactionAllowed());
- ConnectionHolder conHolder =
- (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
- txObject.setConnectionHolder(conHolder, false);
- return txObject;
- }
在比如事务的开始,
[java]- /**
- * This implementation sets the isolation level but ignores the timeout.
- */
- @Override
- protected void doBegin(Object transaction, TransactionDefinition definition) {
- DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
- Connection con = null;
- try {
- if (txObject.getConnectionHolder() == null ||
- txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
- Connection newCon = this.dataSource.getConnection();
- if (logger.isDebugEnabled()) {
- logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
- }
- txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
- }
- txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
- con = txObject.getConnectionHolder().getConnection();
- Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
- txObject.setPreviousIsolationLevel(previousIsolationLevel);
- // Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
- // so we don't want to do it unnecessarily (for example if we've explicitly
- // configured the connection pool to set it already).
- if (con.getAutoCommit()) {
- txObject.setMustRestoreAutoCommit(true);
- if (logger.isDebugEnabled()) {
- logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
- }
- con.setAutoCommit(false);
- }
- txObject.getConnectionHolder().setTransactionActive(true);
- int timeout = determineTimeout(definition);
- if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
- txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
- }
- // Bind the session holder to the thread.
- if (txObject.isNewConnectionHolder()) {
- TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
- }
- }
- catch (Exception ex) {
- DataSourceUtils.releaseConnection(con, this.dataSource);
- throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
- }
- }
等等这里就不多说了,起个头。
评论暂时关闭