七、hibernate的事务使用
hibernate中事务隔离级别
- 1:读未提交
- 2:读已提交
- 4:可重复读
- 8:可串行化
hibernate事务使用
- 在核心配置文件中配置事务隔离级别
- <property name="hibernate.connection.isolation">4</property>
- 确保一个逻辑事务中的session是同一个
- 核心配置文件中配置事务当前线程绑定session:<property name="hibernate.current_session_context_class" >thread</property>
- 通过sessionFactory.getCurrentSession()来获取session(getCurrentSession()方法默认不开启,必须配置事务当前线程绑定session来开启)
- 注:使用getCurrentSession()方法获取的session操作完不需要关闭,线程结束会自动关闭
核心配置文件hibernate.cfg.xml
<hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class" >com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url" >jdbc:mysql:///test02</property> <property name="hibernate.connection.username" >root</property> <property name="hibernate.connection.password" >root</property> <property name="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.hbm2ddl.auto" >create</property> <property name="hibernate.show_sql" >true</property> <!-- <property name="hibernate.format_sql" >true</property> --> <property name="hibernate.connection.isolation">4</property> <property name="hibernate.current_session_context_class" >thread</property> <mapping resource="com/qf/entity/Teacher.hbm.xml"/> <mapping resource="com/qf/entity/Student.hbm.xml"/> </session-factory> </hibernate-configuration>
sessionFactory.getCurrentSession()方法的实现
内部使用了ThreadLocal来实现线程绑定session
public Session getCurrentSession() throws HibernateException { if ( currentSessionContext == null ) { throw new HibernateException( "No CurrentSessionContext configured!" ); } return currentSessionContext.currentSession(); }
@Override public final Session currentSession() throws HibernateException { Session current = existingSession( factory() ); if ( current == null ) { current = buildOrObtainSession(); // register a cleanup sync current.getTransaction().registerSynchronization( buildCleanupSynch() ); // wrap the session in the transaction-protection proxy if ( needsWrapping( current ) ) { current = wrap( current ); } // then bind it doBind( current, factory() ); } else { validateExistingSession( current ); } return current; }
1. 测试getCurrentSession()方法获取的session操作完是否会自己关闭
@Test public void test() { Configuration cfg = new Configuration().configure(); SessionFactory factory = cfg.buildSessionFactory(); Session session = factory.getCurrentSession(); Transaction tx = session.beginTransaction(); Student student = session.get(Student.class, 1L); System.out.println(student); tx.commit(); session.close(); }
-------------------------------------Junit-----------------------------------------
org.hibernate.SessionException: Session was already closed
线程结束,session已经自己关闭了,不需要再去手动关闭
2. 测试两次通过getCurrentSession()方法获取的session是否一致
@Test public void test() { Configuration cfg = new Configuration().configure(); SessionFactory factory = cfg.buildSessionFactory(); Session session1 = factory.getCurrentSession(); Session session2 = factory.getCurrentSession(); System.out.println("两次通过getCurrentSession()获取的session是否一致:"+(session1==session2)); Session session3 = factory.openSession(); Session session4 = factory.openSession(); System.out.println("两次通过openSession()获取的session是否一致:"+(session3==session4)); }
-------------------------------------console-----------------------------------------
两次通过getCurrentSession()获取的session是否一致:true 两次通过openSession()获取的session是否一致:false