`
ycljf86
  • 浏览: 77497 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

sessionFactory session

阅读更多
sessionFactory 为何是线程安全的,看了源码才知道,里面的类变量大都是final的。
session为何不线程安全,看了源码才知道,里面变量大都是transient的

sessionfactory:
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;



session:

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;
    
    private transient String fetchProfile;

    private transient Map enabledFilters = new HashMap();

    private transient Session rootSession;
    private transient Map childSessionsByEntityMode;

    private EntityNameResolver entityNameResolver = new   CoordinatingEntityNameResolver();




sessionfactory中
private transient boolean isClosed = false;
private transient SchemaExport schemaExport;
这两个都是提供读操作  所以无所谓线程安全 而且SF的开启 关闭 都是交给容器的,一般线程是不会改变它的,所以他里面的实例变量不会改变,isClose()确实被SF实现类提供,是暴露的,但是不是说一个类暴露了变量,那么这个类就一定是不安全的,这里所谓的安全主要是指是否能有效控制并发。而所谓并发控制首先需要明确的是边界,并发控制的边界我认为是:"从你执行‘读’到你执行‘写’这一过程中有没有其它的人‘写入’。一个暴露的变量如果从功能设计上的目的只是为了提供‘读取’的目的,那么即使暴露也不会产生任何预期的并发冲突。

之所以说要认识到Session是非线程安全的,主要是提醒大家,在自己开发的调用类中,不要将Session设置为成员变量,而是要将Session写在方法中,这样得到的Session才是因线程而异的.方法运行每个线程都有自己的栈内存 所以互补影响

另外在sping的opensessioninview环境中,
session与connection的关系,很多人认为  session不关那么connection就不会断开。这个是错误的。Session不是Connection,打开一个Session并不一定打开一个数据库连接。只有在开启事务后,连接才会打开,并在提交事务时关闭连接。当通过该Session再次开启事务时再次获取数据库连接。这样保证对数据库资源使用时间最短,同时充分享受Session一级缓存带来的便利。
Session共享的说法在“一次请求一个会话”中仅仅是请求内共享缓存;在“一次对话一个会话”中可以做到更大程度的共享,不过没有特殊应用场景和适当的理由,是不建议使用的。
根据集中查询、集中计算、集中提交的原则,如果计算很费时,就需要在一次请求过程中的Session分别进行两次的数据库事务的启动和提交,而不是一个长事务。
我觉得有些人对Spring的事务管理不满意,可能就是Spring简单的通过AOP方式在Service层面上作事务管理,无法更灵活的选择吧。

session只有当你真正需要访问数据库的时候才获取链接,然后在事务提交过后释放链接(Spring中是这样实现的)。也就是说,当你Session s=SessionFactory.openSession();的时候session并没有获得数据库链接,甚至在Query q=s.createQuery(hql)时都没有获得连接,真正获得连接是在q.list()的时候。当然还有其他时候。。。。

在spring管理下的SESSION,只要你记得提交事务,就没有问题
如果是纯hibernate,想在一个存活实际很长的线程中共享session,那么是否考虑一下当不需要连接的时候 session.disconnect()(好像有这个方法,虽然不推荐使用了)。此时session的一级缓存还在,要再次连接数据库的时候就重新获得 session。如何?

或者,用完了session就直接close


只有经过事务的配置之后hibernate的session才能被关闭,当然,关闭session还会涉及到懒加载导致在JSP页面中获取关系对象的异常,这个也有办法解决,spring提供了OpenSessionInViewFilter这个类,就是hibernate的session生命周期被延迟到执行完JSP之后才关闭


要是不在spring环境中 会怎么样?
分享到:
评论

相关推荐

    HibernateSession , Transaction 研究

    `SessionFactory`是`Session`的工厂,负责创建和配置`Session`。`SessionFactory`一般在应用启动时创建并缓存,避免频繁创建和关闭带来的性能开销。 在开发中,使用Hibernate的`Session`和`Transaction`能够有效...

    hibernate--3.Hibernate数据持久化(通过 Session 操纵对象)

    Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); MyEntity entity = new MyEntity(); entity.setName("Some Name"); session.save(entity); transaction...

    getCurrentSession 与 openSession() 的区别

    Session session = sessionFactory.openSession(); // 打开新Session session.beginTransaction(); // 开始事务 // 数据库操作 session.getTransaction().commit(); // 提交事务 session.close(); // 关闭Session ``...

    基于Java的数据持久层框架 Hibernate.zip

    3. **创建Session**: 使用SessionFactory创建Session,每个数据库事务通常在一个新的Session中进行。 4. **操作实体**: 在Session中,开发者可以对实体进行增、删、改、查操作。比如,使用`save()`方法保存新实体,...

    Hibernate(基础)

    5. **使用 Session 插入数据**:通过 SessionFactory 创建 Session,然后调用 `save()` 或 `saveOrUpdate()` 方法保存实体对象到数据库。示例代码如下: ```java SessionFactory sessionFactory = ...; // 初始化 ...

    Hibernate Part 2:单表CRUD

    Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); User user = new User(); user.setUsername("test"); user.setPassword("test123"); session.save(user...

    hibernate 连接数据库基础源码2

    3. **获取Session**: 使用SessionFactory的`openSession()`方法创建Session实例,Session是与数据库交互的接口。 4. **开始事务**: 使用Session的`beginTransaction()`方法开启一个新的数据库事务。 5. **操作...

    hibernate教程

    //2、创建SessionFactory Session session = sf.openSession(); //3、打开Session Transaction tx = session.beginTransaction(); //4、开始事务 在 Hibernate 中,实体类是与数据库表相对应的 Java 类,例如这里...

    纯hibernate增删改差基本操作,入门实例.

    Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); ``` **5. CRUD 操作** - **Create(创建)**: 使用 `session.save()` 或 `session.persist()` 方法将新...

    java hibernate 实例

    Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); User user = new User(); user.setUsername("test"); user.setPassword("test123"); session.save(user)...

    Hibernate事务(源码)

    Session session = sessionFactory.openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); // 执行数据库操作 session.save(entity); transaction.commit(); } ...

    spring hibernate执行存储过程的例子

    Session session = sessionFactory.openSession(); String sql = "CALL your_procedure(?, ?)"; SQLQuery query = session.createSQLQuery(sql).addEntity(YourResultEntity.class); query.setParameter(1, param1)...

    java大作业:java实现数据库的底层实现

    Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); User user = new User(); // 设置user的属性 session.save(user); // 插入新用户 transaction.commit()...

    新Hibernate SessionFactory().getCurrentSession()猫腻

    总结来说,这篇博客文章可能探讨了在使用Hibernate时,通过SessionFactory().getCurrentSession()获取Session的技巧和注意事项,包括如何正确配置Spring事务管理、理解线程绑定的Session机制,以及如何利用源码和...

    Java Hibernate

    - **管理会话**:通过 Hibernate 提供的 `SessionFactory` 创建 `Session`,并通过 `Session` 执行 CRUD 操作。 - **执行查询**:可以使用 SQL 或 HQL 进行查询,并利用 `Session` 的 API 完成数据的检索。 #### ...

    hibernate一对多映射的例子

    Session session = sessionFactory.openSession(); session.beginTransaction(); session.save(audi); // 保存品牌,会同时保存所有关联的车型 session.getTransaction().commit(); session.close(); ``` 在这个...

    Hibernate3 参考手册中文版.pdf

    - **Session 和 SessionFactory**:SessionFactory 是 Hibernate 的核心工厂类,负责创建 Session 实例。Session 代表了与数据库的一次会话,是所有数据操作的基础。 - **持久化对象**:在 Hibernate 中,可以通过...

    hibernate many-to-many级联保存,级联更新,级联删除

    Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); // 创建Student和Course对象 Student student = new Student(); Course course = new Course(); // ...

    我用这个方法来执行查询操作

    SessionFactory session = HibernateSessionFactory.getSession(); ``` - **会话工厂**:`HibernateSessionFactory`通常是一个单例模式实现的类,用于管理`SessionFactory`实例。通过它来获取`SessionFactory`,进而...

    HibernateSessionFactory 代码

    Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); MyEntity entity = new MyEntity(); // 设置属性... session.save(entity); tx.commit(); session.close(); ``` *...

Global site tag (gtag.js) - Google Analytics