Hibernate框架(13) —— Hibernate中的事务

本文详细介绍了Hibernate框架中的事务特性,包括原子性、一致性、隔离性和持久性,并讨论了事务并发问题及其解决方案——隔离级别。同时,文章还阐述了在Hibernate中如何设置数据库的隔离级别,以及在实际项目中如何管理和优化事务处理,强调了在同一事务中使用getSession()的重要性。

一、事务特性

    A 原子性:最小不可分割的单位(要么全成功,要么全失败)

    B 一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

      比如转账,转账前两个账户的余额是1000,转账后两个账户的余额也是1000。

    C 隔离性:多线程环境下,一个线程中的事务不能被其他线程中的事务打扰。

    D 持久性:事务一旦提交,就应该被永久保存起来。

二、事务并发问题

    A 脏读:读到了其他人正在操作的数据。

    B 不可重复读:两次连续的读取,数据不一致。

    C 幻(虚)读:一个线程中的事务读取到另一个线程中insert提交的数据。

三、事务的隔离级别(用来解决事务并发问题)

    A 读未提交——可能出现 ABC

    B 读已提交——BC

    C 可重复读——C (MySQL默认级别)

    D 串行化——没有问题,效率太低

四、在Hibernate中指定数据库的隔离级别

    #hibernate.connection.isolation 1|2|4|8

    使用一个字节指定隔离级别

    0001 —— 1 (读未提交)

    0010 —— 2 (读已提交)

    0100 —— 4 (可重复读)

    1000 —— 8 (串行化)

    hibernate.cfg.xml

    <!--指定hibernate操作数据库时的隔离级别-->(项目实际情况定隔离级别)

    <property name=”hibernate.connection.isolation”>4</property>

五、在项目中如何管理事务

    A  业务开始之前打开事务,业务执行之后提交事务。

       执行过程中出现异常,回滚事务。

    B  在DAO层操作数据库需要用到session对象。

       在service控制事务也是使用session对象完成。我们需要确保DAO层和service层使用同一个session对象。

    C 在hibernate中,确保使用同一个session的问题,

      hibernate已经解决了,开发人员只需要调用sf.getCurrentSession()即可获得与当前线程绑定的session对象。

    注意1:调用getCurrentSession方法必须配合主配置文件中的一段配置。

    hibernate.cfg.xml

    <property name=”hibernate.current_session_context_class”>thread</property>

    public void function1() {

       //每次返回与线程绑定的session

       Session session1 = HibernateUtils.getCurrentSession();

       Session session2 = HibernateUtils.getCurrentSession();

       System.out.println(“session1 == session2”);//true

    }

    public void function2() {

       //每次获得新的session

       Session session1 =HibernateUtils.openSession();

       Session session2 =HibernateUtils.openSession();

       System.out.println(“session1 == session2”);//false

    }

    注意2:通过getCurrentSession()获得的session对象,当事务提交时,session会自动关闭,不要手动调用close关闭。

六、代码优化

public class CustomerDaoImpl implements CustomerDao {

    public void save(Customer c) {

        1.获得session

        Sessionsession = HibernateUtils.openSession();

        2.打开事务

        Transactiontx = session.beginTransaction();

        3.执行保存

        session.save();

        4.提交事务

        tx.commit();

        5.关闭资源

        session.close();

    }

}

public class CustomerDaoImpl implements CustomerDao {

    public void save(Customer c) {

        1.获得session

        Session session = HibernateUtils.getCurrentSession();

        2.执行保存

        session.save();

    }

}

public class CustomerServiceImpl implements CustomerService {

    private CustomerDao customerDao = new CustomerDaoImpl();

    public void save(Customer c) {

        Session session = HibernateUtils.getCurrentSession();

        1. 打开事务

        Transaction tx =session.beginTransaction();

        2. 调用Dao保存客户

        try {

            customerDao.save(c);

        } catch (Exception e) {

            e.printStackTrace();

            3. 事务回滚

            tx.rollback();

        }

        3. 关闭事务

        tx.commit();

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值