日期:2014-05-19  浏览次数:20738 次

SessionFactory是线程安全的,Session是非线程安全的,如何正确理解?
去看了SessionFactoryImpl的源码。里面的实例变量大部分是final类型的,不可改变。但是有两个transient类型非final的。

  再看SessionImpl的源码。大部分的实例变量是transient非final类型的。但是有一个

  private EntityNameResolver entityNameResolver = new CoordinatingEntityNameResolver();

  这如何解释实例变量影响线程安全呢?


Java code

public final class SessionFactoryImpl implements SessionFactory, SessionFactoryImplementor {

    private static final Logger log = LoggerFactory.getLogger(SessionFactoryImpl.class);
    private static final IdentifierGenerator UUID_GENERATOR = new UUIDHexGenerator();

    private final String name;
    private final String uuid;

    private final transient Map entityPersisters;
    private final transient Map classMetadata;
    private final transient Map collectionPersisters;
    private final transient Map collectionMetadata;
    private final transient Map collectionRolesByEntityParticipant;
    private final transient Map identifierGenerators;
    private final transient Map namedQueries;
    private final transient Map namedSqlQueries;
    private final transient Map sqlResultSetMappings;
    private final transient Map filters;
    private final transient Map imports;
    private final transient Interceptor interceptor;
    private final transient Settings settings;
    private final transient Properties properties;
    private transient SchemaExport schemaExport;
    private final transient TransactionManager transactionManager;
    private final transient QueryCache queryCache;
    private final transient UpdateTimestampsCache updateTimestampsCache;
    private final transient Map queryCaches;
    private final transient Map allCacheRegions = new HashMap();
    private final transient StatisticsImpl statistics = new StatisticsImpl(this);
    private final transient EventListeners eventListeners;
    private final transient CurrentSessionContext currentSessionContext;
    private final transient EntityNotFoundDelegate entityNotFoundDelegate;
    private final transient SQLFunctionRegistry sqlFunctionRegistry;
    private final transient SessionFactoryObserver observer;
    private final transient HashMap entityNameResolvers = new HashMap();

    private final QueryPlanCache queryPlanCache = new QueryPlanCache( this );

    private transient boolean isClosed = false;





Java code

public final class SessionImpl extends AbstractSessionImpl
        implements EventSource, org.hibernate.classic.Session, JDBCContext.Context {

    // todo : need to find a clean way to handle the "event source" role
    // a seperate classs responsible for generating/dispatching events just duplicates most of the Session methods...
    // passing around seperate reto interceptor, factory, actionQueue, and persistentContext is not manageable...

    private static final Logger log = LoggerFactory.getLogger(SessionImpl.class);

    private transient EntityMode entityMode = EntityMode.POJO;
    private transient boolean autoClear; //for EJB3
    
    private transient long timestamp;
    private transient FlushMode flushMode = FlushMode.AUTO;
    private transient CacheMode cacheMode = CacheMode.NORMAL;

    private transient Interceptor interceptor;

    private transient int dontFlushFromFind = 0;

    private transient ActionQueue actionQueue;
    private transient StatefulPersistenceContext persistenceContext;
    private transient JDBCContext jdbcContext;
    private transient EventListeners listeners;

    private transient boolean flushBeforeCompletionEnabled;
    private transient boolean autoCloseSessionEnabled;
    private transient ConnectionReleaseMode connectionReleaseMode;