1. Overview of the transaction
A transaction is a set of data operations performed as a single logical unit of work that either must be all successful or must fail all to ensure the consistency and integrity of the data. Transaction has ACID properties:
Atomicity: The smallest of nature, the content of a business either doing or not doing
Consistency: The state is consistent after the transaction ends, and the system state and business logic rules are consistent
Isolation: Is the lock mechanism, multiple transaction access to the same data is separated
Persistence: Once the transaction is over, the result of the transaction is permanently preserved
Database Transaction Management
The ACID properties of a database transaction are implemented by a relational database management system (RDBMS). The database management system uses logs to ensure the atomicity, consistency, and durability of transactions.
The database management system adopts the lock mechanism to realize the separation of the transaction.
Transaction management in 2.Hibernate applications
Hibernate the Lightweight object encapsulation of JDBC, hibernate itself does not have the transaction processing function at design time, usually uses the hibernate transaction, Just the bottom of the jdbctransaction or jtatransaction to carry out a package, on the outside of the transaction and session of the shell, in fact, the bottom is entrusted to the bottom of the JDBC or JTA to implement the transaction scheduling function.
1) using JDBC transactions in Hibernate
To use a JDBC transaction in hibernate, you can specify the hibernate transaction as Jdbctransaction in Hibernate.cfg.xml. Note: JDBC transactions are used by default if they are not configured.
<property name= "Hibernate.transaction.factory_class" >
Org.hibernate.transaction.JDBCTransactionFactory
</property>
Transaction Tx=null;
try{
Tx=session.begintransaction ();
Perform a persistent operation
Tx.commit ();
}catch (Exception e) {
if (tx!=null) Tx.rollback ();
Throw e;
} finally{
Session.close ();
}
2) Use of JTA transactions in Hibernate
The JTA (Java Transaction API) can be simply understood as a cross database transaction, implemented by the application JTA container. You need to configure the Hibernate.transaction.factory_class parameter using Jtatransaction, which defaults to org.hibernate.transaction. Jdbctransactionfactory, When using jtatransaction, you need to change the parameter to Org.hibernate.transaction.JTATransactionFactory and configure the Jta.usertransaction parameter Jndi name ( Hibernate to find javax.transaction.UserTransaction in the context of Jndi when starting jtatransaction.
Javax.transaction.UserTransactin tx = Context.lookup ("Jndiname");
try{
Tx.begin ();
Session operation of multiple databases;
Session1 .....
Session2 .....
Tx.commit ();
}catch (Exception e) {
Tx.rollback (); Throw e;
}
3. Concurrent access Control
problems caused by database transaction concurrency:
Lost Update: When you change the time I also changed, I changed the content of your modified or modified content rolled back, not saved in.
Dirty read: Read dirty data, you read after I modified, you read the content is not valid or rollback, I modified half you read the last I have to roll back.
Non-repeat read: two times the contents of the query are not the same; the second read was modified.
Phantom reads: two times the contents of the query are not the same; the second query found something different from the first, possibly because someone in the middle made a change or deleted it.
Transaction ISOLATION Level: in order to solve problems caused by multiple transactions concurrency, the user is given a reasonable trade-off between the isolation and concurrency of the transaction as needed. The database system provides 4 kinds of transaction isolation levels.
READ UNCOMMITTED (READ UNCOMMITTED): lowest isolation Level
Read submitted (Read Committed): In general, use this
REPEATABLE READ (Repeatable Read)
Serialization (Serializable): The highest isolation level, so concurrency problems are not
The database system uses different lock types to implement these 4 isolation levels. The implementation process is transparent to the user, as long as the user chooses the appropriate isolation level.
The higher the isolation level, the greater the assurance of data integrity and consistency, but the greater the impact on concurrency performance. For most applications, the isolation level of Read Committed is preferred, which avoids hidden reads and has better concurrency performance.
The hibernate configuration file can display the settings isolation level. Each isolation level is for a positive integer.
Read uncommitted:1
Read Committed:2
Repeatable Read:4
Serializable:8
<property name= "Hibernate.connection.isolation" >2</property>
4. Optimistic concurrency control
When the database system uses the Read Committed isolation level, it is still not possible to prevent non-duplication and phantom reads. In situations where this problem can occur, optimistic locking and pessimistic locking are used in the application.
Optimistic locking is the assumption that when the current transaction operates on a database resource, no other transactions are being accessed concurrently, so there is no lock on the database level. To maintain the correct data, hibernate is implemented using version and timestamp.
1 Use version number for version control
Define a version property in the persisted class. The type can only be integral type.
Add <version> tag to the mapping file, and be sure to put it behind the <id> element.
5. Pessimistic concurrency control
Pessimistic lock is the assumption that the current transaction operations data resources, there must be other transactions at the same time access to the data resource, so lock the resource first.
The general implementation is implemented by the database, using exclusive locks to lock resources. Using get (), load (), is the specified lock mode can be displayed: Lockmode.upgrade
Session.get (Student.class,1,lockmode.upgrade);
6. Configure the C3P0 connection pool
<!--enable C3P0 connection pooling to set up the provider for connection pooling-->
<property name= "Connection.provider_class" >org.hibernate.connection.c3p0connectionprovider</property >
Maximum connection number of <!---->
<property name= "C3p0.max_size" >20</property>
<!--minimum connection number-->
<property name= "C3p0.min_size" >5</property>
<!--number of connections per request-->
<property name= "C3p0.acquire_increment" >5</property>
<!--set the expiration time, in seconds, if the connection pool-the idle connection exceeds this time, the connection is removed from the connection pool-->
<property name= "C3p0.timeout" >120</property>
<!--Check the free connections in the connection pool every 3,000 seconds-->
<property name= "C3p0.idle_test_period" >3000</property>
7. Hibernate not suitable for the scene
It is not suitable for OLAP (On-line Analytical processing online analytical Processing) to query the system based on analysis data, and for OLTP (on-line transaction processing online transaction processing).
For some relational model design unreasonable old system, also can not play hibernate advantage. Large amount of data, demanding performance systems, Hibernate also difficult to meet the requirements, the efficiency of the bulk operation of the data is not high.
1). Hibernate Consolidation Struts
The hibernate framework is primarily used in the persistence layer to complete the CRUD operations of the entity classes.
2). hibenate implementation of generic DAO pattern
3). Opensessioninview mode
8. Case analysis
Hibernate.cfg.xml To configure the following data:
<property name= "Hibernate.connection.isolation" >2</property>
configuration in the mapping file:
<version name= "Version" ></version>
@Test
Test optimistic lock; Add data, build number automatically generate without manually adding
publicvoid Testadd () {
Session session = Hibernateutil.getsession ();
Session.begintransaction ();
User U = new user ();
U.setname ("Dick");
U.setbirthday (new Date ());
Session.save (U);
Session.gettransaction (). commit ();
Hibernateutil.close ();
}
@Test
Test optimistic lock; change data, the version number will automatically add 1
publicvoid testupdate () {
Session session = Hibernateutil.getsession ();
Session.begintransaction ();
User user = (user) session.load (user). Class, 4);
User.setname ("Harry");
Session.gettransaction (). commit ();
Hibernateutil.close ();
}
@Test
Simple simulation of transactions in Hibernate; However, the error will be detected: Transaction not successfully started; But the experiment shows that the value of the second modification is saved to the database
publicvoid testtransaction () {
Session Session1 = Hibernateutil.getsession ();
Session1.begintransaction ();
User User1 = (user) session1.load (user). Class, 4);
Session Session2 = Hibernateutil.getsession ();
Session2.begintransaction ();
User User2 = (user) session1.load (user). Class, 4);
User1.setname ("AA");
User2.setname ("BB");
Session1.gettransaction (). commit ();
Session2.gettransaction (). commit ();
Hibernateutil.close ();
}
@Test
Test pessimistic lock, in the same resource class to do the test when you must remember to note the optimistic lock settings, especially in the mapping file version of the label, which can be easily modified, changed to property properties and then do the experiment
Result: The SELECT statement at this time is different from the usual, where the condition is more than one sentence: where user0_.id=? For update
publicvoid Find () {
Session session = Hibernateutil.getsession ();
Session.begintransaction ();
User user = (user) session.load (user). Class, 4,lockmode.upgrade);
System.out.println (User.getname () + "----" +user.getbirthday ());
Session.gettransaction (). commit ();
Hibernateutil.close ();
}