zoukankan      html  css  js  c++  java
  • spring的事物实现

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

  • 相关阅读:
    day23
    day22
    day21
    day20
    小程序 组件操作
    jmeter安装使用一
    小程序登录操作
    Django ORM DateTimeField 时间误差8小时问题
    小程序初始篇
    ADB命令
  • 原文地址:https://www.cnblogs.com/zpitbolg/p/5094752.html
Copyright © 2011-2022 走看看