4.1 トランザクションとデータベースの整合性

データベースの通常の動作モードでは、数百の異なるクライアントから毎分数千のリクエストが受信されます。この場合、同じデータが異なるクエリからアクセスされるという状況がよく発生します。

頻度はそれほど多くありませんが、1 つのリクエストが特定の行を読み取り、同時に別のリクエストがその行を変更する状況が時々発生します。誰かが半分しか変更されていない行を読んだらどうなるかを想像してみてください。何も良いことがない。

この問題はいくつかの方法で解決されます。まず、変更される行をロックするだけです。読むにも書くにも。この方法は機能しますが、ベースの速度が大幅に低下します。

2 番目の方法は、文字列を書き込み専用にロックする方法です。ただし、部分的に変更された行を読み取ろうとすると、依然として問題が発生します。結論 - 行が部分的に変更される状況はあってはならない。

そこで、彼らは 3 番目の方法であるトランザクションを思いつきました。トランザクションは、すべて同時に実行されるか、まったく実行されないアクションのグループです。アクションの一部が実行され、2 番目の部分が実行されないという状況はあり得ません。すべての変更を行うことができない場合は、すでに行われたすべての変更がロールバックされます。

最新の SQL サーバーでは、トランザクション内でのみデータを変更できます。トランザクションを開き、任意の数のテーブルに変更を加えて、トランザクションをコミットします。その後、SQL Server は変更を加えようとします。すべてが正常であれば、それらは一般データベースに追加されます。問題があった場合は、すべての変更がキャンセルされます。

Hibernate もこのパラダイムを使用します。前回の講義で、Employee オブジェクトをデータベースに保存しようとすると、最初にトランザクションが開かれ、保存後にトランザクションがコミットされることを説明したのはこのためです。

このトピックについては後ほど詳しく説明しますが、ここでは、トランザクションが必要な理由とトランザクションが通常どこで使用されるかを知っておいてください。

4.2 オブジェクトの取得

Hibernate がデータを取得するリクエストを実行する場合、明示的にトランザクションを開く必要はありません。Hibernate 自体は、適切と判断した場合にこれを実行します。Hibernate には SQL サーバーの設定だけでなく、Hibernate の設定も含まれています。

データベースの操作方法を分析します。最も単純なのは、 IDによってオブジェクトを取得することです。これを行うには、セッションget()オブジェクトのメソッドを使用します。このようなリクエストの一般的な形式は次のとおりです。

Class Name = session.get(Class.class, ID);

例:

public User getUserById(Integer id) {
    try (Session session = sessionFactory.openSession()) {
        User user = session.get(User.class, id);
        return user;
    }
}

4.3 オブジェクトの保存(追加)

オブジェクトをデータベースに保存する場合は、クエリが SQL レベルで実行されます。入れる。したがって、アクションは別のトランザクションとして実行する必要があります。また、永続化にはセッションpersist()オブジェクトのメソッドを使用することをお勧めします。

このようなリクエストの一般的な形式は次のとおりです。

session.persist(An object);

このメソッドはpersist()ベースだけでなくオブジェクト自体も変更します。問題は、オブジェクトをデータベースに追加するとき、このオブジェクトは追加する前にはまだ独自のIDを持っていないということです。まあ、ニュアンスはありますが、通常はそうです。追加後、オブジェクトにはすでにID が割り当てられています。

public boolean saveUser(User user) {
    try (Session session = sessionFactory.openSession()) {
            Transaction transaction = session.beginTransaction();
            session.persist(user);
            transaction.commit();
            return true;
    }
    catch() {
    return false;
   	}
}

Sessionオブジェクトにも、save()同様の機能を実行するメソッドがあります。ただ、メソッドがsave()古い Hibernate 標準であり、メソッドがpersist()JPA 標準であるというだけです。

4.4 オブジェクトの削除

既存のオブジェクトを削除したい場合は、非常に簡単に削除できます。これを行うために、セッション オブジェクトには特別なメソッドがあります - remove()

このようなリクエストの一般的な形式は次のとおりです。

session.remove(An object);

そしてもちろん、例を使ってコードを書いてみましょう。

public boolean removeUser(User user) {
    try (Session session = sessionFactory.openSession()) {
            Transaction transaction = session.beginTransaction();
            session.remove(user);
            transaction.commit();
            return true;
    }
    catch() {
    return false;
   	}
}

なぜそんなに難しいのですか?

まず第一に、データベースに変更を加えると常に異なる結果が生じ、必ずしも明らかな結果が得られるわけではありません。次に、このオブジェクトには子オブジェクトが関連付けられている可能性があるため、削除シナリオは多くの場合簡単ではありません。