zoukankan      html  css  js  c++  java
  • 六、持久层框架(Hibernate)

    一、乐观锁

      Hibernate使用乐观锁来处理脏数据问题。

    比如有这样一个制造脏数据的场景:

    1、通过session1得到id=1的对象product1

    2、在product1原来的价格基础上增加100

    3、更新product1之前,通过session2得到id=1的对象product2

    4、在product2原来的价格基础上增加100

    5、更新product1

    6、更新product2

    但是最后product的价格只增加了100,而不是200.

    二、在不使用乐观锁的情况下代码如下:

    package com.demo.test;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    import com.demo.pojo.Product;
    
    public class TestHibernate{
        public static void main(String[] args){
            SessionFactory sf=new Configuration().configure().buildSessionFactory();
            Session session1=sf.openSession();
            Session session2=sf.openSession();
            
            session1.beginTransaction();
            session2.beginTransaction();
            
            Product p1=(Product)session1.get(Product.class,1);
            System.out.println("原来的基础价格:"+p1.getPrice());//原来基础价格为100
            
            p1.setPrice(p1.getPrice()+100);
            
            Product p2=(Product)session2.get(Product.class,1);
            p2.setPrice(p2.getPrice()+100);
            
            session1.update(p1);
            session2.update(p2);
            session1.getTransaction().commit();
            session2.getTransaction().commit();
            
            Product p=(Product)session1.get(Product.class,1);
            System.out.println("经过两次价格增加,价格变为:"p.getPrice());//经过两次后才为200
            
            session1.close();
            session2.close();
            sf.close();
        }
    }
    View Code

    三、在使用乐观锁的情况

    1、修改配置文件Product.hbm.xml

    增加一个version标签字段,用于版本信息控制,这就是乐观锁的核心机制。

    <version name="version" column="ver" type="int"></version>

    比如session1获取product1的时候,version=1.那么session1更新product1的时候,就需要确保version还是1才可以进行更新,并且更新结束后,把version改为2

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
    <hibernate-mapping package="com.demo.pojo">
        <class name="Product" table="product_">
            <id name="id" column="id">
                <generator class="native">
                </generator>
            </id>
            <!--version元素必须紧挨着id后面  -->
            <version name="version" column="ver" type="int"></version>
            <property name="name" />
            <property name="price" />
    
            <many-to-one name="category" class="Category" column="cid" />
    
            <set name="users" table="user_product" lazy="false">
                <key column="pid" />
                <many-to-many column="uid" class="User" />
            </set>
    
        </class>
    
    </hibernate-mapping>
    View Code

    注:version元素必须紧跟在id后面否则会报错。id是表的主键

    2、修改Product.java实体类

      增加version属性

    package com.demo.pojo;
     
    import java.util.Set;
     
    public class Product {
        int id;
        String name;
        float price;
        Category category;
        int version;
        public int getVersion() {
            return version;
        }
        public void setVersion(int version) {
            this.version = version;
        }
        Set<User> users;
     
        public Set<User> getUsers() {
            return users;
        }
        public void setUsers(Set<User> users) {
            this.users = users;
        }
        public Category getCategory() {
            return category;
        }
        public void setCategory(Category category) {
            this.category = category;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public float getPrice() {
            return price;
        }
        public void setPrice(float price) {
            this.price = price;
        }
         
    }
    View Code

    3、运行同样的TestHibernate

      提示做同样的业务就会抛出异常,提示该行已经被其他事物删除或者修改过了,本次修改无法生效。这样就保证了数据的一致性。

    package com.demo.test;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    import com.demo.pojo.Product;
    
    public class TestHibernate{
        public static void main(String[] args){
            SessionFactory sf=new Configuration().configure().buildSessionFactory();
            Session session1=sf.openSession();
            Session session2=sf.openSession();
            
            session1.beginTransaction();
            session2.beginTransaction();
            
            Product p1=(Product)session1.get(Product.class,1);
            System.out.println("原来的基础价格:"+p1.getPrice());//原来基础价格为100
            
            p1.setPrice(p1.getPrice()+100);
            
            Product p2=(Product)session2.get(Product.class,1);
            p2.setPrice(p2.getPrice()+100);
            
            session1.update(p1);
            session2.update(p2);
            session1.getTransaction().commit();
            session2.getTransaction().commit();
            
            Product p=(Product)session1.get(Product.class,1);
            System.out.println("经过两次价格增加,价格变为:"p.getPrice());//经过两次后才为200
            
            session1.close();
            session2.close();
            sf.close();
        }
    }
    View Code

    四、使用乐观锁的原理

    1、假设数据库的产品价格是100,version是1

    2、session1,session2分别获取了对象

    3、都修改了对象的价格

    4、session1保存到数据库,检测version=1,成功保存,并把version修改为2

    5、session2保存到数据库,检测到version=2,说明数据已经被其他人动过了,保存失败,然后抛出异常。

  • 相关阅读:
    51nod乘积之和
    Dell服务器安装OpenManage(OMSA)
    Nginx反向代理PHP
    搭建haproxy
    108. Convert Sorted Array to Binary Search Tree
    60. Permutation Sequence
    142. Linked List Cycle II
    129. Sum Root to Leaf Numbers
    118. Pascal's Triangle
    26. Remove Duplicates from Sorted Array
  • 原文地址:https://www.cnblogs.com/drq1/p/8532199.html
Copyright © 2011-2022 走看看