Hibernate study notes 8, session management, transaction control

Transaction Management in Hibernate

Transaction (Transaction) is the basic logical unit of work, which can be used to ensure that the database can be modified correctly, to avoid the data being modified only in part, resulting in incomplete data, or user interference when modifying. As a software designer, it is imperative to understand transactions and utilize them appropriately to ensure that the database holds correct and complete data. The database provides the user with a method to save the current program state, which is called transaction commit; during the execution of a transaction, the method to make the database ignore the current state and return to the previously saved state is called transaction rollback.

1 Characteristics of transactions

Transactions have four attributes: Atomicity, Consistency, Isolation, and Durability, or ACID for short. These four characteristics are described below.

Atomicity: Bundle the operations done in a transaction into an atomic unit, that is, for operations such as data modification performed by the transaction, either all or none of them are performed.

Consistency: When a transaction completes, all data must be in a consistent state, and in related data, all rules must be applied to the modification of the transaction to maintain the integrity of all data. At the end of the transaction, all internal data structures should be correct.

Isolation: Modifications made by concurrent transactions must be isolated from modifications made by any other transaction. The state of the data when the transaction views the data, either before being modified by another concurrent transaction, or after being modified by another concurrent transaction, that is, the transaction will not view the data being modified by another concurrent transaction. This isolation method is also called serializability.

Durability: After a transaction completes, its impact on the system is permanent, even in the event of a system failure.

2 Transaction isolation

Transaction isolation means that for a running transaction, it seems that there is only one transaction in the system and no other concurrent transactions exist. In most cases, fully isolated transactions are rarely used. However, transactions that are not completely isolated will bring the following problems.
Lost Update (Lost Update): Both transactions attempt to update a row of data, causing the transaction to throw an exception and exit, and the updates of both transactions are in vain.  Dirty data (Dirty Read): If the second application uses the data modified by the first application, and this data is in an uncommitted state, a dirty read occurs. The first application may then request that the modified data be rolled back, causing the data used by the second transaction to be corrupted, so-called "dirty".  Unrepeatable Read: A transaction reads the same row of data twice, but the data read two times is different, it is called unrepeatable read. Unreread occurs when one transaction can modify and delete data before another transaction commits it.  Phantom Read: A transaction executes two queries and finds that the result of the second query has one more row than the first query. This may be because another transaction inserted a new row between the two queries. . In view of the above problems caused by incomplete isolation of transactions, some isolation levels are proposed to prevent these problems.  Read Uncommitted (Read Uncommitted): Before a transaction is committed, its changes are visible to other transactions. Dirty reads, unrepeatable reads, and phantom reads are all allowed. When a transaction has written a row of data but has not committed it, no other transaction can write this row of data; however, any transaction can read any data. This isolation level is implemented using write-exclusive locks.  Read Committed (Read Committed): Reading uncommitted data is not allowed. It is implemented using temporary common read locks and write row locks. This isolation level does not allow dirty reads, but non-repeatable and phantom reads are allowed.  Repeatable Read: The transaction guarantees that the same data can be read again without failure. Dirty reads and unrepeatable reads are not allowed at this isolation level, but phantom reads can occur.  Serializable (Serializable): Provides the strictest transaction isolation. This isolation level does not allow parallel execution of transactions, only serial execution. In this way, dirty reads, unrepeatable reads, or phantom reads can all occur.
The relationship between transaction isolation and isolation level is shown in Table 1.
Table 1 Relationship between transaction isolation and isolation level
write picture description here
In a practical application, developers are often not sure what isolation level to use. Too severe level will reduce the performance of concurrent transactions, but insufficient isolation level will produce some small bugs, and these bugs will only appear when the system is under heavy load (that is, when the concurrency is severe).
In general, Read Uncommitted is dangerous. The rollback or failure of a transaction will affect another parallel transaction, or leave data in memory that is inconsistent with the database. This data may be read by another transaction and committed to the database. This is totally not allowed.
In addition, most programs do not require Serializable Isolation. Although, it does not allow phantom reads, but generally speaking, phantom reads are not a big problem. Serializable isolation requires a large system overhead, and few people use this transaction isolation mode in actual development.
The optional isolation levels that remain now are Read Committed and Repeatable Read. Hibernate can well support Repeatable Read isolation level.
3 Set the isolation level in the Hibernate configuration file.
The JDBC connection database uses the default isolation level, namely Read Committed and Repeatable Read. In Hibernate's configuration file hibernate.properties, you can modify the isolation level:

#hibernate.connection.isolation 4

In the previous line of code, the isolation level of the Hibernate transaction is 4. What does this mean? The numerical meanings of the levels are as follows.

1: Read Uncommitted 2: Read Committed 4: Repeatable Read 8: Serializable

So the number 4 means the "rereadable" isolation level. If the above statement is to be valid, the comment character "#" before the statement line should be removed:

hibernate.connection.isolation 4

You can also add the following code to the configuration file hibernate.cfg.xml:

<session-factory>
//把隔离级别设置为4
<property name= hibernate.connection.isolation”>4</property>
</session-factory>

Before starting a transaction, Hibernate obtains the isolation level value from the configuration file.


Where does transaction control take place?

Execute in service():

service(){
    session.beginTransaction;//开启事务
    try{
    调用dao方法1
    调用dao方法2
    .....
    session.getTransaction().commit();//提交事务
    }catch(Exception ex){
        session.getTransaction().rollback();//回滚事务
    }
}

How session is managed

In the service interface, the same session is used in each dao request, that is, the same database connection is used to ensure that multiple dao calls are in one transaction.

Open a new session at the beginning of service execution, bind the session to the current thread, and obtain the session bound to the current thread in each dao call, so that the session obtained by each dao is the same session.
write picture description here


4.2 Get the session bound to the current thread


Manually write code in the tool class

write picture description here
(code)

    //定义一个treadLocal,存储当前线程绑定的session
    private static ThreadLocal<Session> session_threadLocal = new ThreadLocal<Session>();
    //获取当前线程绑定的session
    public static Session getCurrentSession() {

        Session session = session_threadLocal.get();

        if(session == null) {
            //开启一个新的session
            session = sessionFactory.openSession();
            //将新开启的session和当前线程绑定
            session_threadLocal.set(session);
            return session;
        }
        return session;
    }

    //关闭当前线程绑定的session
    public static void closeCurrentSession() {

        Session session = session_threadLocal.get();

        if(session != null) {
            session.close();
            session_threadLocal.set(null); 
        }
    }

Modify dao and service (see study notes 6 for the content before modification)


daomodification

CstCustomerDaoImpl class (code)

    public void insert(CstCustomer customer) {

        //获取当前线程绑定的session
        Session session = HibernateUtil.getCurrentSession();
        session.save(customer);
    }

CstCustomerDetailDaoImpl类(code)

    public void insert(CstCustomerDetail customerDetail) {
        //获取当前线程绑定的session
        Session session = HibernateUtil.getCurrentSession();
        session.save(customerDetail);
    }
}

The life cycle of the Session object is bound to the local thread

Add the following configuration in hibernate.cfg.xml:

    <!-- 配置session绑定本地线程 -->
    <property name="hibernate.current_session_context_class">thread</property>

Service modification (focusing on the control of transaction Transaction)

CustomerServiceImpl类(code)

    //实现事务控制
    @Override
    public void insertCustomer(CstCustomer cstCustomer, CstCustomerDetail cstCustomerDetail) {

        //开启session与当前线程绑定
        Session session = HibernateUtil.getCurrentSession();
        //开事务
        session.beginTransaction();

        try {
            //执行单元
            CstCustomerDao CstCustomerDao = new CstCustomerDaoImpl();
            CstCustomerDetailDao CstCustomerDeatailDao = new CstCustomerDetailDaoImpl();
            //插入基本信息
            CstCustomerDao.insert(cstCustomer);
            //基本信息和详细信息的主键保持一致
            cstCustomerDetail.setCustId(cstCustomer.getCustId());
            //插入详细信息
            CstCustomerDeatailDao.insert(cstCustomerDetail);
            //提交事务
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {
            //关闭当前线程的session
            HibernateUtil.closeCurrentSession();
        }
    }

hibernate support for transaction management

Hibernate 5 itself provides three methods for managing Session objects:
Session object life cycle and local thread binding
Session object life cycle and JTA transaction binding
Hibernate delegate program manages Session object life cycle


The Hibernate framework itself also has the function of transaction control and management, so the manual thread binding method of the above tool class can be changed to the built-in method of Hibernate's sessionFactory, and the modification is as follows:
(code)

    //获取当前线程绑定的session
    public static Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    //关闭当前线程绑定的session
    public static void closeCurrentSession() {

        sessionFactory.getCurrentSession().close();
    }
}

Manage session threads. When multiple tables are operating at the same time, let them share the same session, which can improve the integrity of database table operations. If there is an error in the middle, the whole process will stop to avoid the appearance of the operation table in the middle. Errors that result in omission of operations on other tables.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324402341&siteId=291194637