Hibernate对于Web应用程序更安全吗?

Hibernate对于Web应用程序更安全吗?,第1张

Hibernate对于Web应用程序更安全吗?

1) 在Hibernate中,每个应用程序都存在一个 SessionFactory对象
SessionFactory的内部状态不可变的因此是线程安全的 。多个线程可以同时访问它以获取Session实例。

下面的代码描述了通过Utility类获取SessionFactory实例的标准方法。

import org.hibernate.SessionFactory;import org.hibernate.cfg.AnnotationConfiguration;public class HibernateUtil {private static final SessionFactory sessionFactory;//once created, its properties cannot be changedstatic {    try {        // Create the SessionFactory from standard (hibernate.cfg.xml) config file.        sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();    } catch (Throwable ex) {        // Log the exception.        System.err.println("Initial SessionFactory creation failed." + ex);        throw new ExceptionInInitializerError(ex);    }}public static SessionFactory getSessionFactory() {    return sessionFactory;}}

2) Hibernate Session
是Java应用程序层和hibernate之间的接口。这是用于执行数据库 *** 作的核心接口。会话的生命周期受逻辑事务的开始和结束的限制。

Hibernate Session对象不是线程安全的 ,每个线程都应获取其自己的会话实例,并在工作完成后将其关闭。

实现者不是线程安全的。相反,每个线程/事务都应从SessionFactory获取其自己的实例。

A typical transaction should use the following idiom: Session sess = factory.openSession(); Transaction tx; try {     tx = sess.beginTransaction();     //do some work     ...     tx.commit();     } catch (Exception e) {    if (tx!=null) tx.rollback();    throw e; } finally {      sess.close(); }

如果会话引发异常,则必须回滚事务并丢弃会话。 发生异常后,会话的内部状态可能与数据库不一致。

2.1) 下面列出了两种广泛用于获取Hibernate会话对象的方法。

  1. openSession //在 多线程 环境中使用
  2. getCurrentSession //将其用于 单线程 环境

Hibernate SessionFactory的 getCurrentSession()方法返回绑定到上下文的会话。
但是要使其正常工作,我们需要在hibernate配置文件中对其进行配置。由于此会话对象属于hibernate上下文,因此我们无需关闭它。一旦SessionFactory关闭,该会话对象就被关闭。

<property name="hibernate.current_session_context_class">thread</property>

Hibernate SessionFactory的 openSession() 方法总是打开一个新的会话。一旦完成所有数据库 *** 作,就应该
关闭 该会话对象。
我们应该在多线程环境中为每个请求打开一个新会话。


2.2)还有另外一种使用openStatelessSession()创建Hibernate
Session对象的方法,它为您提供了一个hibernate的无状态会话。

它是一个面向命令的API,用于对数据库执行批量 *** 作。
无状态会话不会实现一级缓存,也不会与任何二级缓存交互,也不会实现事务后写或自动脏检查,也不会将 *** 作级联到关联的实例。无状态会话将忽略集合。通过无状态会话执行的 *** 作会绕过Hibernate的事件模型和拦截器。由于缺少一级缓存,无状态会话很容易受到数据别名的影响。

对于某些类型的事务,无状态会话的执行速度可能比有状态会话的执行速度稍快(例如:批处理/批量更新)

StatelessSession session = sessionFactory.openStatelessSession();Transaction tx = session.beginTransaction();ScrollableResults customers = session.getNamedQuery("GetCustomers").scroll(ScrollMode.FORWARD_ONLY);while ( customers.next() ) {Customer customer = (Customer) customers.get(0);customer.updateStuff(...);session.update(customer);}tx.commit();session.close();

在此代码示例中,查询返回的Customer实例将立即分离。它们从不与任何持久性上下文相关联。

由StatelessSession接口定义的insert(),update()和delete() *** 作被视为直接数据库行级 *** 作。它们分别导致立即执行SQL
INSERT,UPDATE或DELETE。

无状态会话不是线程安全的 ,使用无状态会话为“
org.hibernate.AssertionFailure:可能对该会话的非线程安全访问”时可能发生异常


3)
您的学生记录项目是一个多线程应用程序,因此在使用hibernate模式时需要格外小心。尝试通过打开新会话,使用事务,提交和回滚以及在需要时关闭会话来使用最佳编程实践。

我个人在我们的项目中使用过hibernate,那里有数百万的用户通过hibernate作为后端API访问数据库。由于我们使用了hibernate的最佳编程实践,因此我们在多线程环境中从未遇到过此类问题。即使数据库发生任何异常,整个事务也会回滚。

因此,与JDBC相比,可以以更高的成功率实现数据库事务的ACID属性(原子性,一致性,隔离性,持久性)。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5168945.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-11-18
下一篇2022-11-18

发表评论

登录后才能评论

评论列表(0条)

    保存