Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate对于Web应用程序更安全吗?_Java_Mysql_Multithreading_Hibernate_Servlets - Fatal编程技术网

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

Java Hibernate对于Web应用程序更安全吗?,java,mysql,multithreading,hibernate,servlets,Java,Mysql,Multithreading,Hibernate,Servlets,我怀疑Hibernate对于web应用程序(JSP、Servlet、Hibernate、MySQL)是否安全,因为在这些应用程序中,“不同的用户”可以“一次”访问数千次 我担心的原因如下 假设我有一个面向学生的web应用程序。他们有自己的个人资料,并将维护自己的学生课程、分数等。现在,肯定会有超过1个用户一直在线,拥有自己的个人资料。这意味着,如果用户A对他的数学分数进行了编辑,则将在用户As配置文件中进行编辑。在所有同时在线的用户A、B和'C'的个人资料中,它永远不会被替换 servlet是多

我怀疑
Hibernate
对于web应用程序(JSP、Servlet、Hibernate、MySQL)是否安全,因为在这些应用程序中,“不同的用户”可以“一次”访问数千次

我担心的原因如下

假设我有一个面向学生的web应用程序。他们有自己的个人资料,并将维护自己的学生课程、分数等。现在,肯定会有超过1个用户一直在线,拥有自己的个人资料。这意味着,如果用户
A
对他的数学分数进行了编辑,则将在用户
A
s配置文件中进行编辑。在所有同时在线的用户
A
B
和'C'的个人资料中,它永远不会被替换

servlet
是多线程的,以提供上述支持。它与纯JDBC的预期效果相当好。如何使用
Hibernate

我还上传了我的
HibernateUtil
,供您参考。在我的例子中,我将其称为
SessionFactoryBuilder

public class SessionFactoryBuilder
{
    private static SessionFactoryBuilder instance;
    private static SessionFactory sessionFactory;

    private SessionFactoryBuilder()
    {
        buildConfig();
        System.out.println("hehehehe");
    }

    private static void buildConfig()
    {
        Configuration configuration = new Configuration().configure();
            StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties());
            sessionFactory = configuration.buildSessionFactory(builder.build());
    }

    public static SessionFactoryBuilder getInstance()
    {
         if(instance == null)
         {
            instance = new SessionFactoryBuilder();

         }
      return instance;
    }

    public SessionFactory getSessionFactory()
    {
        return sessionFactory;
    }

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

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

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

/**
 * Hibernate Utility class with a method to get Session Factory object.
 */
public class HibernateUtil {
private static final SessionFactory sessionFactory;//Once created, its properties cannot be changed

static {
    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)HibernateSession是java应用层和Hibernate之间的接口。这是用于执行数据库操作的核心接口。 会话的生命周期以逻辑事务的开始和结束为界限

Hibernate会话对象不是线程安全的,每个线程都应该获得自己的会话实例,并在工作完成后关闭它

这并不意味着实现者是线程安全的。相反,每个线程/事务应该从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会话对象的方法

  • openSession//将其用于多线程环境
  • getCurrentSession//将其用于单线程环境
  • Hibernate SessionFactorygetCurrentSession()方法返回绑定到上下文的会话。但要使其工作,我们需要在Hibernate配置文件中对其进行配置。由于此会话对象属于hibernate上下文,因此不需要关闭它。关闭SessionFactory后,此会话对象将关闭

    <property name="hibernate.current_session_context_class">thread</property>
    
    在此代码示例中,查询返回的客户实例将立即分离。它们从不与任何持久性上下文关联

    由无状态会话接口定义的insert()、update()和delete()操作被认为是直接的数据库行级操作。它们分别导致立即执行SQL插入、更新或删除

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


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

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

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

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

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

    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.AnnotationConfiguration;
    
    /**
     * Hibernate Utility class with a method to get Session Factory object.
     */
    public class HibernateUtil {
    private static final SessionFactory sessionFactory;//Once created, its properties cannot be changed
    
    static {
        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)HibernateSession是java应用层和Hibernate之间的接口。这是用于执行数据库操作的核心接口。 会话的生命周期以逻辑事务的开始和结束为界限

    Hibernate会话对象不是线程安全的,每个线程都应该获得自己的会话实例,并在工作完成后关闭它

    这并不意味着实现者是线程安全的。相反,每个线程/事务应该从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会话对象的方法

  • openSession//将其用于多线程环境
  • getCurrentSession//将其用于单线程环境
  • Hibernate SessionFactorygetCurrentSession()方法返回会话绑定