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环境中 会怎么样?
分享到:
相关推荐
`SessionFactory`是`Session`的工厂,负责创建和配置`Session`。`SessionFactory`一般在应用启动时创建并缓存,避免频繁创建和关闭带来的性能开销。 在开发中,使用Hibernate的`Session`和`Transaction`能够有效...
Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); MyEntity entity = new MyEntity(); entity.setName("Some Name"); session.save(entity); transaction...
Session session = sessionFactory.openSession(); // 打开新Session session.beginTransaction(); // 开始事务 // 数据库操作 session.getTransaction().commit(); // 提交事务 session.close(); // 关闭Session ``...
3. **创建Session**: 使用SessionFactory创建Session,每个数据库事务通常在一个新的Session中进行。 4. **操作实体**: 在Session中,开发者可以对实体进行增、删、改、查操作。比如,使用`save()`方法保存新实体,...
5. **使用 Session 插入数据**:通过 SessionFactory 创建 Session,然后调用 `save()` 或 `saveOrUpdate()` 方法保存实体对象到数据库。示例代码如下: ```java SessionFactory sessionFactory = ...; // 初始化 ...
Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); User user = new User(); user.setUsername("test"); user.setPassword("test123"); session.save(user...
3. **获取Session**: 使用SessionFactory的`openSession()`方法创建Session实例,Session是与数据库交互的接口。 4. **开始事务**: 使用Session的`beginTransaction()`方法开启一个新的数据库事务。 5. **操作...
//2、创建SessionFactory Session session = sf.openSession(); //3、打开Session Transaction tx = session.beginTransaction(); //4、开始事务 在 Hibernate 中,实体类是与数据库表相对应的 Java 类,例如这里...
Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); ``` **5. CRUD 操作** - **Create(创建)**: 使用 `session.save()` 或 `session.persist()` 方法将新...
Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); User user = new User(); user.setUsername("test"); user.setPassword("test123"); session.save(user)...
Session session = sessionFactory.openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); // 执行数据库操作 session.save(entity); transaction.commit(); } ...
Session session = sessionFactory.openSession(); String sql = "CALL your_procedure(?, ?)"; SQLQuery query = session.createSQLQuery(sql).addEntity(YourResultEntity.class); query.setParameter(1, param1)...
Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); User user = new User(); // 设置user的属性 session.save(user); // 插入新用户 transaction.commit()...
总结来说,这篇博客文章可能探讨了在使用Hibernate时,通过SessionFactory().getCurrentSession()获取Session的技巧和注意事项,包括如何正确配置Spring事务管理、理解线程绑定的Session机制,以及如何利用源码和...
- **管理会话**:通过 Hibernate 提供的 `SessionFactory` 创建 `Session`,并通过 `Session` 执行 CRUD 操作。 - **执行查询**:可以使用 SQL 或 HQL 进行查询,并利用 `Session` 的 API 完成数据的检索。 #### ...
Session session = sessionFactory.openSession(); session.beginTransaction(); session.save(audi); // 保存品牌,会同时保存所有关联的车型 session.getTransaction().commit(); session.close(); ``` 在这个...
- **Session 和 SessionFactory**:SessionFactory 是 Hibernate 的核心工厂类,负责创建 Session 实例。Session 代表了与数据库的一次会话,是所有数据操作的基础。 - **持久化对象**:在 Hibernate 中,可以通过...
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`,进而...
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); MyEntity entity = new MyEntity(); // 设置属性... session.save(entity); tx.commit(); session.close(); ``` *...