Spring的事物主要有三个接口
PlatformTransactionManager、
根据TransactionDefinition配置的事物信息创建事物
TransactionDefinition
主要描述控制具体事物行为的属性,比如事物隔离级别,超时时间,传播行为等
TransactionStatus
代表了事物具体的运行状态
Spring事物的具体实现是交给底层持久化框架实现的,如下:
hibernate3 HibernateTransactionManger
jdbc DataSourceTransactionManger
类图简单如下:
PlatformTransactionManager
|
|
AbstractPlatformTransactionManager
| |
| |
HibernateTransactionManger DataSourceTransactionManger
PlatformTransactionManager只是简单定义了事物的公共方法
public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException; }
通过模板方法模式调用底层事物管理器的实现,比如commit方法
public final void commit(TransactionStatus status) throws TransactionException { if (status.isCompleted()) { throw new IllegalTransactionStateException( "Transaction is already completed - do not call commit or rollback more than once per transaction"); } DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status; if (defStatus.isLocalRollbackOnly()) { if (defStatus.isDebug()) { logger.debug("Transactional code has requested rollback"); } processRollback(defStatus); return; } if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) { if (defStatus.isDebug()) { logger.debug("Global transaction is marked as rollback-only but transactional code requested commit"); } processRollback(defStatus); // Throw UnexpectedRollbackException only at outermost transaction boundary // or if explicitly asked to. if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) { throw new UnexpectedRollbackException( "Transaction rolled back because it has been marked as rollback-only"); } return; } processCommit(defStatus); }
processCommit方法会调用具体事物管理器的具体实现,比如jdb的事物管理器
@Override protected void doCommit(DefaultTransactionStatus status) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction(); Connection con = txObject.getConnectionHolder().getConnection(); if (status.isDebug()) { logger.debug("Committing JDBC transaction on Connection [" + con + "]"); } try { con.commit(); } catch (SQLException ex) { throw new TransactionSystemException("Could not commit JDBC transaction", ex); } }
通常我们一个方法里面有可能有多个事物操作,spring是怎样保证,是在同一个事物下进行的呢?
spring为此定义了事物同步管理器
spring将jdbc的Connection hibernate的session等统称为资源
要实现操作是在同一个事物下进行的,则要保证处理操作的线程是用的同一个资源操作的,比如jdbc的Connection,如果方法内几个操作是用的
同一个Connection进行操作的,就可以统一的进行事物的控制。
那么怎么样才能保证线程拿到的是统一的资源呢?
spring使用了threadlocal进行实现
事物管理器的类如下:
public abstract class TransactionSynchronizationManager { private static final Log logger = LogFactory.getLog(TransactionSynchronizationManager.class); //用于保存每个线程对connection或者session的资源 private static final ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal<Map<Object, Object>>("Transactional resources"); private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations = new NamedThreadLocal<Set<TransactionSynchronization>>("Transaction synchronizations"); //用于保存每个事物线程对应事物名称 private static final ThreadLocal<String> currentTransactionName = new NamedThreadLocal<String>("Current transaction name"); private static final ThreadLocal<Boolean> currentTransactionReadOnly = new NamedThreadLocal<Boolean>("Current transaction read-only status"); private static final ThreadLocal<Integer> currentTransactionIsolationLevel = new NamedThreadLocal<Integer>("Current transaction isolation level"); private static final ThreadLocal<Boolean> actualTransactionActive = new NamedThreadLocal<Boolean>("Actual transaction active"); ........................... }
为此spring提供了一套获取资源的公共类,比如
jdbc mybits 对应DataSourceUtils
hibernate3对应SessionFastoryUtils等
这样当底层事物管理器操作资源的时候,会通过事物资源管理器操作事物,因为事物资源管理器获取或者操作的资源都是在当前线程内(threadlocal实现),所以能够保证是同一个,这样spring就实现了事物的控制。