zoukankan      html  css  js  c++  java
  • hibernate框架学习笔记6:事务

    MySQL的事务、JDBC事务操作:

    详细见这篇文章:比较详细

    http://www.cnblogs.com/xuyiqing/p/8430214.html

    如何在hibernate中配置隔离级别:

    再核心配置文件中:

             <!-- 指定hibernate操作数据库时的隔离级别 
                #hibernate.connection.isolation 1|2|4|8        
                0001    1    读未提交
                0010    2    读已提交
                0100    4    可重复读
                1000    8    串行化
             -->
             <property name="hibernate.connection.isolation">4</property>                

    这里是二进制,转换成十进制就是1,2,4,8

    项目中管理事务:

    没有学习hibernate框架以前,在项目中,开启事务在业务层(service),执行之后提交或回滚

    而在hibernate框架中,也是这样,操作数据库需要用到的session对象,一定保证,service层和dao层的session是同一个

    类似servlet项目中需要确保service层和dao层的connection对象一致,当时用到了绑定线程

    (这是以前sevlet项目中的一个工具类,可以浏览下对比)

    package utils;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import javax.sql.DataSource;
    
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    
    public class DataSourceUtils {
    
        private static DataSource dataSource = new ComboPooledDataSource();
    
        private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
    
        // 直接可以获取一个连接池
        public static DataSource getDataSource() {
            return dataSource;
        }
    
        // 获取连接对象
        public static Connection getConnection() throws SQLException {
    
            Connection con = tl.get();
            if (con == null) {
                con = dataSource.getConnection();
                tl.set(con);
            }
            return con;
        }
    
        // 开启事务
        public static void startTransaction() throws SQLException {
            Connection con = getConnection();
            if (con != null) {
                con.setAutoCommit(false);
            }
        }
    
        // 事务回滚
        public static void rollback() throws SQLException {
            Connection con = getConnection();
            if (con != null) {
                con.rollback();
            }
        }
    
        // 提交并且 关闭资源及从ThreadLocall中释放
        public static void commitAndRelease() throws SQLException {
            Connection con = getConnection();
            if (con != null) {
                con.commit(); // 事务提交
                con.close();// 关闭资源
                tl.remove();// 从线程绑定中移除
            }
        }
    
        // 关闭资源方法
        public static void closeConnection() throws SQLException {
            Connection con = getConnection();
            if (con != null) {
                con.close();
            }
        }
    
        public static void closeStatement(Statement st) throws SQLException {
            if (st != null) {
                st.close();
            }
        }
    
        public static void closeResultSet(ResultSet rs) throws SQLException {
            if (rs != null) {
                rs.close();
            }
        }
    
    }
    View Code

    在hibernate框架中,原理是一样的,绑定线程

    但是,只需要在核心配置文件中配置:

             <!-- 指定session与当前线程绑定 -->
             <property name="hibernate.current_session_context_class">thread</property>

    代码只需一行:

                    SessionFactory sf = new Configuration().configure().buildSessionFactory();
                    sf.getCurrentSession();

    简单的测试即可理解:

    package demo;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;
    import org.junit.Test;
    
    import utils.HibernateUtils;
    
    //测试getCurrentSession
    public class Demo {
    
        @Test
        //返回同一个与线程绑定的session
        public void fun1(){
            Session session1 = HibernateUtils.getCurrentSession();
            Session session2 = HibernateUtils.getCurrentSession();
            
            System.out.println(session1==session2);//true
        }
        
        @Test
        //返回不同的session
        public void fun2(){
            Session session1 = HibernateUtils.openSession();
            Session session2 = HibernateUtils.openSession();
            
            System.out.println(session1==session2);//false
        }
        
        
    }

    补上工具类:

    package utils;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    public class HibernateUtils {
        private static SessionFactory sf;
        
        static{
            //1 创建,调用空参构造
            Configuration conf = new Configuration().configure();
            //2 根据配置信息,创建 SessionFactory对象
             sf = conf.buildSessionFactory();
        }
        
        //获得session => 获得全新session
        public static Session openSession(){
                    //3 获得session
                    Session session = sf.openSession();
                    
                    return session;
            
        }
        //获得session => 获得与线程绑定的session
        public static Session getCurrentSession(){
            //3 获得session
            Session session = sf.getCurrentSession();
            
            return session;
        }    
    }
    View Code

    注意:

    通过getCurrentSession方法获得的session对象,事务提交时候,会自动关闭session,不要手动关闭,否则会有异常

  • 相关阅读:
    Linux系统 Docker RabbitMQ容器集群部署
    Linux系统 SSH免密登入
    ubuntu server 乱码
    简单总结在github上托管工程
    在线编译系统之nodejs执行shell
    Ubuntu中软件安装与卸载
    ubuntu软件安装
    “cannot find module ‘npmlog’….”的错误
    关于事件的一点小总结
    mongodb基本操作
  • 原文地址:https://www.cnblogs.com/xuyiqing/p/8449167.html
Copyright © 2011-2022 走看看