演示hibernate如何产生丢失更新的


丢失更新是怎么玩的?首先两个事务先都把它查出来。

A事务里面去修改的数据没了,被B事务覆盖掉了。这是被B事务提交覆盖,B事务回滚也能覆盖。这就是丢失更新的效果。


悲观锁使用了数据库的锁机制,

这就是悲观锁的解决方案,但是这种方式并不是特别的好。因为这条记录被锁定了,其他人都不能操作这条记录了。必须等排它锁被释放完其他人才能操作,这是悲观锁来解决。


乐观锁来解决。

这是关于session的一些本地操作,一会我们来说它。


乐观锁是怎么做的?相当于在我们这里加了一个版本号。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.itcast.vo"><!-- 如果这里配置了包名下面可以不用写 -->
<!--
<hibernate-mapping>
-->
<!--
<class name="cn.itcast.hibernate3.demo2.Customer" table="customer">
-->
<!--
<class name="cn.itcast.vo.Customer" table="customer">
-->
<class name="Customer" batch-size="2" table="customer">
<!-- 配置唯一标识 -->
<id name="cid" column="cid">
<generator class="native"/>
</id>
<!-- version标签是版本号 -->
<version name="version"></version>
<!-- 配置普通属性 -->
<property name="cname" column="cname" length="30"/>
<property name="age" column="age" length="30"/> <!-- 建立映射 -->
<!-- 配置一个集合 <set>的name Customer对象中的关联对象的属性名称. -->
<!-- 这里把级联去掉 要最简短的配置
<set name="orders" cascade="save-update" inverse="true">
-->
<set name="orders" cascade="save-update" batch-size="2">
<!-- <key>标签中column:用来描述一对多多的一方的外键的名称. -->
<key column="cno"></key>
<!-- 配置一个<one-to-many>标签中class属性:订单的类的全路径 -->
<!--
<one-to-many class="cn.itcast.hibernate3.demo2.Order"/>
-->
<one-to-many class="cn.itcast.vo.Order"/>
</set>
</class>
<!-- 命名查询的方式 -->
<query name="findAll">
from Customer
</query>
<!-- 这里要写sql语句
<sql-query> </sql-query>
-->
</hibernate-mapping>
package cn.itcast.test;

import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import cn.itcast.utils.HibernateUtils;
import cn.itcast.vo.Customer; /**
*
* Hibernate的事务管理:
* @author zhongzh
*
*/
public class HibernateDemo3 {
@Test
/*
* 使用乐观锁解决丢失更新 也需要两个事务同时操作这条记录。
*/
public void demo6(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction(); Customer customer = (Customer) session.get(Customer.class, 3);
customer.setAge(26);
tx.commit();
session.close();
}
@Test
/*
* 使用乐观锁解决丢失更新
*/
public void demo5(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction(); Customer customer = (Customer) session.get(Customer.class, 3);
customer.setCname("沈明贞"); tx.commit();
session.close();
}
@Test
/*
* 使用悲观锁解决丢失更新 底层执行的是同一个,只不过事务不一样而已
*/
public void demo4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
// 使用悲观锁(排它锁)
@SuppressWarnings("deprecation")
Customer customer = (Customer) session.get(Customer.class, 3, LockMode.UPGRADE);
customer.setAge(32);
tx.commit();
session.close();
}
@Test
/*
* 使用悲观锁解决丢失更新
*/
public void demo3(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
// 使用悲观锁(排它锁)
@SuppressWarnings("deprecation")
Customer customer = (Customer) session.get(Customer.class, 3, LockMode.UPGRADE);
customer.setCname("沈明贞");
tx.commit();
session.close();
} @Test
/*
*
* 丢失更新的产生
*
*/
public void demo2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer = (Customer) session.get(Customer.class, 3);
//再有一个事务去更新customer的年龄
customer.setAge(30);//持久态对象不用手动调update都可以完成更新 //System.out.println(customer);
tx.commit();
session.close();
}
@Test
/*
*
* 丢失更新的产生
*
*/
public void demo1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer = (Customer) session.get(Customer.class, 3);
//假设就有一个事务在更新这个customer的名称
customer.setCname("沈明贞"); //System.out.println(customer);
tx.commit();
session.close();
}
}

day36 10-Hibernate中的事务:解决丢失更新的更多相关文章

  1. 具体解释Hibernate中的事务

    1.前言 上一篇博客解说了Hibernate中的一级缓存,属于Session级别的.这篇博客解说一下Hibernate中的事务机制. 有关事务的概念.请參照通俗易懂数据库中的事务.  2.怎样处理Hi ...

  2. ### Hibernate中的事务与并发 ###

    **事务相关的概念** 1. 什么是事务 * 事务就是逻辑上的一组操作,组成事务的各个执行单元,操作要么全都成功,要么全都失败. * 转账的例子:冠希给美美转钱,扣钱,加钱.两个操作组成了一个事情! ...

  3. 09.Hibernate中的事务与并发

    事务1. 什么是事务 * 事务就是逻辑上的一组操作,组成事务的各个执行单元,操作要么全都成功,要么全都失败. * 转账的例子:冠希给美美转钱,扣钱,加钱.两个操作组成了一个事情! 2. 事务的特性 * ...

  4. Hibernate中的事务隔离问题(脏读、不可重复读、幻读)

    Hibernate中的事务隔离问题(脏读.不可重复读.幻读) 1.事务的特性 事务的四个特性: 1)原子性:事务是进行数据库操作的最小单位,所以组成事务的各种操作是不可分割的 2)一致性:组成事务的各 ...

  5. Hibernate-ORM:10.Hibernate中的分页

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客讲述Hibernate中的分页 hibernate中的分页其实很好写,它通过操作对象的方式,来进行分页 ...

  6. 十三: 悲观锁&乐观锁:解决丢失更新问题

    悲观锁:认为丢失更新一定会出现,可以在查询的时候加入for update 认为丢失更新一定会出现,查询时: select * from account for update;for update :  ...

  7. Hibernate中的事务隔离

    在我们的项目中,老发现程序报告sesssion is closed或者因数据已经被其他事务修改而导致当前事务无法提交,由于系统的运行用户最多也就几十个人,所以考虑使用严格的事务隔离来防止这种类型的问题 ...

  8. spring+hibernate中的事务

    上下文: 从数据库服务器上获取数据可以,保存的时候增加了事务提交,即em.flush方法,报错no transaction in progress 报错信息: no transaction in pr ...

  9. hibernate中的事务管理是怎么概念?

    1.JDBC事务 JDBC 事务是用 Connection 对象控制的.JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交. ja ...

随机推荐

  1. pytorch基础2

    下面是常见函数的代码例子 import torch import numpy as np print("分割线---------------------------------------- ...

  2. echarts高级

    常用,待续... ♣tooltip自动轮播 ♣ 实现数据自动轮播 原理:其实就是timeline,获取某几段(时间)的数据,然后隐藏timeline ♣ legend自动轮播 ♣ 左侧多字出省略号 f ...

  3. Plugin org.apache.maven.plugins:maven-clean-plugin:2.4.1 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-clean-plugin:jar:2.4.1

    Plugin org.apache.maven.plugins:maven-clean-plugin:2.4.1 or one of its dependencies could not be res ...

  4. 抓包:MySQL Sniffer

    1.依赖文件安装 依赖glib2-devel.libpcap-devel.libnet-devel [root@VMUest ~]# yum install cmake [root@VMUest ~] ...

  5. 1、Zookeeper的功能以及工作原理

    1.ZooKeeper是什么? ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交 ...

  6. HashMap 和 concurrentHashMap

    从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...

  7. 多线程同步锁和死锁以及synchronized与static synchronized 的区别

    线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程.一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序.简而言之:一个程序运行后至少有一个进程,一个进程 ...

  8. HBase+Redis

  9. linux下mysql导入导出sql文件

    使用mysqldump导出数据库: # mysqldump -u root -p gzy > gzy.sql # mysqldump -u 数据库连接用户名 -p 目标数据库 > 存储的文 ...

  10. let和const的一些知识点

    let和const 不可以重复声明 不会发生变量提升,因此必须在声明之后使用,否则报错! 只在声明所在的块级作用域内有效 let 同一个作用域内不能重复声明同一个变量: function func() ...