让我们先来看看Hibernate的文档时怎么说的,关于LockMode:
LockMode FORCE
Similiar to UPGRADE except that, for versioned entities, it results in a forced version increment.
LockMode NONE
No lock required.
LockMode READ
A shared lock. Objects in this lock mode were read from the database in the current transaction, rather than being pulled from a cache (注:也就是从数据库中读数据,绕过了Hibernate的Cache)
LockMode UPGRADE
An upgrade lock.(注:相当于SQL语句select xxx from xxxx for update,也就是把事务的处理交给了数据库)
LockMode UPGRADE_NOWAIT
Attempt to obtain an upgrade lock, using an Oracle-style select for update nowait.
LockMode WRITE
A WRITE lock is obtained when an object is updated or inserted.This lock mode is for internal use only and is not a valid mode for load() or lock() (both of which throw exceptions if WRITE is specified). (注:不能在load的时候用,否则抛出异常)
不过,“纸上得来终觉浅,觉知此事要躬行”,博主做了下实验来比较这些“锁”的不同。
先看代码:
package com.javaye;
import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.javaye.models.Article;
public class Main {
private static void insert(){
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
Article art = new Article();
art.setTitle("AAA");
art.setVisitAmount(0);
session.saveOrUpdate(art);
tx.commit();
}
private static void update(){
Session session = HibernateSessionFactory.getSession();
System.out.println("session:"+session.hashCode());
Transaction tx = session.beginTransaction();
Article art = (Article) session.load(Article.class, 1,LockMode.UPGRADE);
System.out.println(" loaded");
art.setVisitAmount(art.getVisitAmount()+1);
session.save(art);
tx.commit();
session.evict(art);
}
private static void work(){
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+":"+(i+1)+"times.");
update();
}
}
public static void main(String[] args) throws Exception{
Thread t1 = new Thread(
new Runnable(){
public void run(){
work();
}
}
);
Thread t2 = new Thread(
new Runnable(){
public void run(){
work();
}
}
);
t1.setName("Thread1");
t2.setName("Thread2");
t1.setDaemon(true);
t2.setDaemon(true);
t1.start();
t2.start();
t1.join();
t2.join();
}
}
这是一个多线程程序,每个线程都会从数据库中取出visit_amount,然后加一,再存回数据库,每个线程重复10遍。
请注意蓝色的部分,我们在这里设一个断点,那么用Eclipse调试的时候,到达这个断点的线程就会停下来,由于它的事务还没有 commit(),LockMode.UPGRADE的锁就还没有释放,那么另外一个线程中事务就会在load的时候因为不能获得锁而阻塞,那么理论上我们只会看到只有一句“ loaded ”输出。 实验结果证明了我的猜想,LockMode.UPGRADE的情况下,如果一个事务获得了锁,即使另外的事务想读取数据也是不行的,必须等待锁的释放。
那么,改写数据可以吗?笔者又做了一个实验,打开MySQL Query Browser,直接生改数据库,把visit_amount字段的值硬生生改过来,结果发现提交的时候就阻塞了,MySQL的海豚标志一个劲的游泳,这说明,LockMode.UPGRADE级别的锁不是由Hibernate控制的,而是由数据库控制的。
再试一试LockeMode.Read,断点还是设在原来的位置,发现有两次“ loaded”输出,证明两个事务可以同时读取这条数据,那么这个锁有什么作用呢?根据我实验的结果,似乎只是为了绕过cache,从数据库直接读取。为了证明我的猜想,我直接通过MySQL Query Browser更改了visit_amount,调试发现,Hibernate是从数据库中读取的新值,而不是cache中的老值。
最后在补充一点,LockMode.UPGRADE加锁是有超时时间的,如果加锁后超过一定的时间不commit,Hibernate会抛出异常。
分享到:
相关推荐
《LockMod:为我的世界开启安全新篇章》 在广受欢迎的沙盒游戏《我的世界》中,玩家可以自由地创造和探索,但有时对于珍贵的资源或精心构建的建筑,玩家可能希望增加一层保护,避免被其他玩家随意破坏。这就引出了...
s变换用的高斯窗函数( 高斯窗是指数窗的一种,它也无负的旁瓣,而且没有旁瓣波动,因而不回引起计算谱中假的极大值或极小值,而且高斯窗频率窗函数的主瓣比指数窗的主瓣窄,分辨率比指数窗有所提高。
2021科大讯飞车辆贷违预测大赛冠军源码+全部资料.zip [资源说明] 1、该项目是团队成员近期最新开发,代码完整,资料齐全,含设计文档等 2、上传的项目源码经过严格测试,功能完善且能正常运行,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的高校学生、教师、科研工作者、行业从业者下载使用,可借鉴学习,也可直接作为毕业设计、课程设计、作业、项目初期立项演示等,也适合小白学习进阶,遇到问题不懂就问,欢迎交流。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 5、不懂配置和运行,可远程教学 欢迎下载,学习使用!
AI图像处理工具包-一键抠图、背景切换、旧照片修复、人像漫画化、视频卡通化(Python+OpenCV+Dlib+TensorFlow).zip [资源说明] 1、该项目是团队成员近期最新开发,代码完整,资料齐全,含设计文档等 2、上传的项目源码经过严格测试,功能完善且能正常运行,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的高校学生、教师、科研工作者、行业从业者下载使用,可借鉴学习,也可直接作为毕业设计、课程设计、作业、项目初期立项演示等,也适合小白学习进阶,遇到问题不懂就问,欢迎交流。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 5、不懂配置和运行,可远程教学 欢迎下载,学习使用!
基于java+springboot+vue+mysql的远程教育网站设计与实现.docx
毕业设计资料,计算机毕业设计,源码,毕业论文,毕业答辩,答辩PPT,Java毕业设计,php毕业设计,ASP.NET毕业设计,毕业指导,计算机作业,php作业,java作业,ASP.NET作业,编程作业,管理系统,网站,app,毕业设计学习,Java学习,php学习,ASP.NET学习,java课程,php课程,ASP.NET课程,答辩技巧,SQLSERVER数据库,Mysql数据库,jdbc,SSM框架,SpringBoot框架,Html5,小程序
蓝牙串口助手,可以连接HC-05等蓝牙模块,实现单片机设备与手机通讯,安卓手机,蓝牙调试助手,具有按键功能!
TriLib 2 是一个跨平台的运行时 3D 模型导入器
人力资源+大数据+薪酬报告+涨薪调薪,在学习、工作生活中,越来越多的事务都会使用到报告,通常情况下,报告的内容含量大、篇幅较长。那么什么样的薪酬报告才是有效的呢?以下是小编精心整理的调薪申请报告,欢迎大家分享。相信老板看到这样的报告,一定会考虑涨薪的哦。