悲观锁和乐观锁是:在事务隔离机制中设置了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();
    }
}

hibernate 悲观锁乐观锁的更多相关文章

  1. Hibernate悲观锁/乐观锁

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

  2. Java并发 行级锁/字段锁/表级锁 乐观锁/悲观锁 共享锁/排他锁 死锁

    原文地址:https://my.oschina.net/oosc/blog/1620279 前言 锁是防止在两个事务操作同一个数据源(表或行)时交互破坏数据的一种机制. 数据库采用封锁技术保证并发操作 ...

  3. Optimistic concurrency control 死锁 悲观锁 乐观锁 自旋锁

    Optimistic concurrency control https://en.wikipedia.org/wiki/Optimistic_concurrency_control Optimist ...

  4. SQL Server 锁机制 悲观锁 乐观锁 实测解析

    先引入一些概念,直接Copy其他Blogs中的,我就不单独写了. 一.为什么会有锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 1.丢失更新 A,B两个用户读同一数据并进行修改,其中 ...

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

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

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

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

  7. Hibernate 悲观锁,乐观锁

    业务逻辑的实现过程中,往往需要保证数据访问的排他性.因此,我们就需要通过一些机制来保证这些数据在某个操作过程中不会被外界修改,这样的机制,在这里,也就是所谓的“锁”,即给我们选定的目标数据上锁,使其无 ...

  8. 【MySQL】悲观锁&乐观锁

    悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍. 悲观锁(Pessimistic Lock) 悲观锁的 ...

  9. innodb 悲观锁,乐观锁

    转 http://www.cnblogs.com/chenwenbiao/archive/2012/06/06/2537508.html CREATE TABLE `products` ( `id` ...

随机推荐

  1. MySql 分页关键字(limit)

    mysql分页关键字: limit m,n --m:表示从哪一行开始查,n:查询多少条 oracle分页关键字:: rownum SqlServer:top(2005以下版本)  row_number ...

  2. Asp.net中web.config配置文件详解

    Web.config文件是一个XML文本文件,它用来储存 ASP.NET Web 应用程序的配置信息(如最常用的设置ASP.NET Web 应用程序的身份验证方式),它可以出现在应用程序的每一个目录中 ...

  3. django static文件的引入方式(转)

    1. 在django project中创建 static文件夹 2.settings.py中配置要在 STATIC_URL = '/static/'  下边 STATICFILES_DIRS = [ ...

  4. POJ 1164 城堡问题【DFS/位运算/种子填充法/染色法】

    1 2 3 4 5 6 7 ############################# 1 # | # | # | | # #####---#####---#---#####---# 2 # # | ...

  5. hdu1269(有向图强连通分量)

    hdu1269 题意 判断对于任意两点是否都可以互相到达(判断有向图强连通分量个数是否为 1 ). 分析 Tarjan 算法实现. code #include<bits/stdc++.h> ...

  6. 加快Vue项目的开发速度

    巧用Webpack Webpack是实现我们前端项目工程化的基础,但其实她的用处远不仅仅如此,我们可以通过Webpack来帮我们做一些自动化的事情.首先我们要了解require.context()这个 ...

  7. oracle enable / disable all constraint

    beginfor i in (select constraint_name, table_name from user_constraints where table_name='') LOOPexe ...

  8. APP换肤

    一.需求说明 当一个APP用户量大的时候,就需要给不同的用户做标签,用来彰显身份.比如QQ的会员,VIP等不同的皮肤功能. 二.实现方法. 所谓不同的皮肤,就是不同的权限(身份)显示不同的本地或者网络 ...

  9. 自动渗透测试工具集APT2

    自动渗透测试工具集APT2   APT2是Kali Linux新增的一款自动渗透测试工具集.它可以进行NMAP扫描,也可以直接读取Nexpose.Nessus和NMAP的扫描结果,然后自动进行渗透测试 ...

  10. luogu P1802 5倍经验日

    题目背景 现在乐斗有活动了!每打一个人可以获得5倍经验!absi2011却无奈的看着那一些比他等级高的好友,想着能否把他们干掉.干掉能拿不少经验的. 题目描述 现在absi2011拿出了x个迷你装药物 ...