悲观锁和乐观锁是:在事务隔离机制中设置了ReadCommited的情况下,两种可以避免不可重复读的方式。

设置成读已提交是考虑到安全和处理速度,保证并发效率,但是在这个情况下仍然需要避免不可重复读这种情况,于是hibernate提供两种锁来解决这个问题。

悲观锁:自己事务完成之前别人不能动数据。依赖于数据库,“for update”

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Account {
    private int id;
    private int balance; //BigDecimal
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getBalance() {
        return balance;
    }
    public void setBalance(int balance) {
        this.balance = balance;
    }
}

测试类:

package com.bjsxt.hibernate;

import java.math.BigDecimal;

import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class HibernateCacheTest {
    private static SessionFactory sf;
   
    @BeforeClass
    public static void beforeClass() {
        sf = new AnnotationConfiguration().configure().buildSessionFactory();
    }
    @AfterClass
    public static void afterClass() {
        sf.close();
    }
   
    @Test
    public void testSchemaExport() {
        new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
    }
   
    @Test
    public void testSave() {
        Session session = sf.openSession();
        session.beginTransaction();
       
        Account a = new Account();
        a.setBalance(100);
        session.save(a);
           
        session.getTransaction().commit();
        session.close();
    }
   
    @Test
    public void testOperation1() {
        Session session = sf.openSession();
        session.beginTransaction();
       
        Account a = (Account)session.load(Account.class, 1);
        int balance = a.getBalance();
        //do some caculations
        balance = balance - 10;
        a.setBalance(balance);
        session.getTransaction().commit();
        session.close();
    }
   
    @Test
    public void testPessimisticLock() {
        Session session = sf.openSession();
        session.beginTransaction();
       
        Account a = (Account)session.load(Account.class, 1, LockMode.UPGRADE);//NOWAIT ORACL支持
        int balance = a.getBalance();
        //do some caculation
        balance = balance - 10;
        a.setBalance(balance);
        session.getTransaction().commit();
        session.close();
    }
   
    public static void main(String[] args) {
        beforeClass();
    }
}

乐观锁:依赖于表的一个字段,该字段每当该条数据被更新了,字段的内容就会变化而且不会和以前重复。将model中加上@Version即可标记该字段。

package com.bjsxt.hibernate;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Version;

@Entity
public class Account {
    private int id;
    private int balance;
    private int version;
    @Version
    public int getVersion() {
        return version;
    }
    public void setVersion(int version) {
        this.version = version;
    }
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getBalance() {
        return balance;
    }
    public void setBalance(int balance) {
        this.balance = balance;
    }
}

测试类:

package com.bjsxt.hibernate;

import java.math.BigDecimal;

import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class HibernateCacheTest {
    private static SessionFactory sf;

@BeforeClass
    public static void beforeClass() {
        sf = new AnnotationConfiguration().configure().buildSessionFactory();
    }

@AfterClass
    public static void afterClass() {
        sf.close();
    }

@Test
    public void testSchemaExport() {
        new SchemaExport(new AnnotationConfiguration().configure()).create(
                false, true);
    }

@Test
    public void testSave() {
        Session session = sf.openSession();
        session.beginTransaction();

Account a = new Account();
        a.setBalance(100);
        session.save(a);

session.getTransaction().commit();
        session.close();
    }

@Test
    public void testOptimisticLock() {
        Session session = sf.openSession();

Session session2 = sf.openSession();

session.beginTransaction();
        Account a1 = (Account) session.load(Account.class, 1);

session2.beginTransaction();
        Account a2 = (Account) session2.load(Account.class, 1);
       
        a1.setBalance(900);
        a2.setBalance(1100);

        session.getTransaction().commit();
        System.out.println(a1.getVersion());

        session2.getTransaction().commit();
        System.out.println(a2.getVersion());

        session.close();
        session2.close();

    }

public static void main(String[] args) {
        beforeClass();
    }
}

转载于:https://www.cnblogs.com/flying607/p/3484241.html

hibernate 悲观锁乐观锁相关推荐

  1. Hibernate悲观锁/乐观锁

    如果需要保证数据访问的排它性,则需对目标数据加"锁",使其无法被其它程序修改 一,悲观锁 对数据被外界(包括本系统当前的其它事务和来自外部系统的事务处理)修改持保守态度,通过数据库 ...

  2. java 对变量加锁_Java最全锁剖析:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁...

    乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度,在Java和数据库中都有此概念对应的实际应用. 1.乐观锁 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会 ...

  3. 【Java 并发编程】线程锁机制 ( 悲观锁 | 乐观锁 | CAS 三大问题 | ABA 问题 | 循环时间长问题 | 多个共享变量原子性问题 )

    文章目录 一.悲观锁 二.乐观锁 三.乐观锁 CAS 三大问题 一.悲观锁 假设有 222 个线程 , 线程 A 和 线程 B ; 线程 A 访问共享资源 , 线程 B 等待 , 一旦线程 A 访问结 ...

  4. Java锁详解:“独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁+线程锁”

    在Java并发场景中,会涉及到各种各样的锁如公平锁,乐观锁,悲观锁等等,这篇文章介绍各种锁的分类: 公平锁/非公平锁 可重入锁 独享锁/共享锁 乐观锁/悲观锁 分段锁 自旋锁 线程锁 乐观锁 VS 悲 ...

  5. innodb 悲观锁 乐观锁_mysql乐观锁、悲观锁、共享锁、排它锁、行锁、表锁

    mysql乐观锁.悲观锁.共享锁.排它锁.行锁.表锁 乐观锁 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使 ...

  6. 最全Java锁详解:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁

    在Java并发场景中,会涉及到各种各样的锁,比如:高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景,这些锁有对应的种类:公平锁,乐观锁,悲观锁等等,这篇文章来详细介绍各种锁的分类: 公 ...

  7. MySQL - 行锁 表锁 乐观锁 悲观锁 读锁 写锁

    MySQL - 行锁 表锁 乐观锁 悲观锁 读锁 写锁 锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足.在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(I ...

  8. 理解悲观锁乐观锁、同步锁、读锁、写锁

    ava 锁分类 Java 中的锁有很多,可以按照不同的功能.种类进行分类,下面是我对 Java 中一些常用锁的分类,包括一些基本的概述 从线程是否需要对资源加锁可以分为 悲观锁 和 乐观锁 从资源已被 ...

  9. mysql悲观群_谈谈mysql的悲观和乐观锁

    悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.之前有写过一篇文章关于并发的处理思路和解决方案,这里我单独将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍一 ...

最新文章

  1. 买笔记本的10大愚蠢表现
  2. java的线程管理器,QuickThread - Java线程池管理器
  3. 2022二区考研及调剂学校汇总
  4. Hive分析窗口函数(一) SUM,AVG,MIN,MAX
  5. 22.循环控制.rs
  6. python分割字符串输出_python字符串分割
  7. POJ 2054 Color a Tree
  8. 基础省选+NOI-第4部分 动态规划
  9. 《南溪的目标检测学习笔记》——验证模式下出现“Process finished with exit code 137 (interrupted by signal 9: SIGKILL)“的问题
  10. Word 分节设置不同起始页码
  11. Android 动画之 View动画 和 帧动画
  12. 【水题】CodeForce 1183A
  13. 网盘背后的秘密(稍作修改)
  14. 常用系统修复软件绿色工具包
  15. Canvas绘制五子棋棋盘
  16. Python爬取微博短视频
  17. 一发入魂!15分钟让你快速入门Python
  18. codevs 2905 足球晋级
  19. Localization of Classified Objects in SLAM using NonparametricStatistics and Clustering(2018,IROS)
  20. Unity3D——加入剑痕效果(PocketRPG Trail插件)

热门文章

  1. Android使用ActionBar和ViewPager切换页面
  2. golang中的urlEncode
  3. 创建存储过程批量插入数据
  4. BIOS INT 10中断功能
  5. linux内核关于io的变迁
  6. 汇编: dup伪指令
  7. 后台技术-JavaWeb项目初识
  8. 深入理解SpringBoot之装配条件
  9. SQL Server 预编译执行SQLs
  10. 微服务架构崛起 能否成为下一代云计算?