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就实现了事物的控制。