事务
事务:一组业务操作,要么全部成功,要么全部不成功。
在Hibernate中设置自动提交事务:
<!-- hibernate.connection.autocommit: 事务自动提交 (真正开发时,不用)
<property name="hibernate.connection.autocommit">true</property>
-->
特性:ACID
- 原子性:整体
- 一致性:数据
- 隔离性:并发
- 持久性:结果
隔离问题:
- 脏读:一个事务读到另一个事务未提交的内容
- 不可重复读:一个事务读到另一个事务已提交的内容(insert)
- 虚读(幻读):一个事务读到另一个事务已提交的内容(update)
隔离级别--解决问题
- readuncommittd,读未提交。存在3个问题。
- readcommitted,读已提交。解决:脏读。存在2个问题。
- repeatableread ,可重复读。解决:脏读、不可重复读。存在1个问题。
- serializable,串行化。单事务。没有问题。
![](https://i-blog.csdnimg.cn/blog_migrate/7411966d9c9032fe9907e3095b068c79.png)
hibernate设置隔离级别
在hibernate.cfg.xml 配置
hibernate.connection.isolation4
![](https://i-blog.csdnimg.cn/blog_migrate/68a3a7fb2b186261a7cbed5d5c708aca.png)
<!-- 改变Hibernate连接数据库的事务隔离级别
1: 读未提交
2: 读已提交
4: 可重复读
8: 串行化
-->
<property name="hibernate.connection.isolation">4</property>
lost update 丢失更新
![](https://i-blog.csdnimg.cn/blog_migrate/064a06517710ace30aa0a0f0ac52ee13.png)
悲观锁:(数据库提供实现) . 默认认为一定会发送别人要修改我使用的数据. 那我就可以为我读取的数据加锁.
丢失更新肯定会发生。
采用数据库锁机制。
读锁:共享锁。读锁可被其他线程所共享,如果是读取的话大家都可以用这把锁读到数据.
select.... from ... lock in share mode; select * from table lock in share mode(读锁、共享锁)
写锁:排他锁。(独占)写锁不能共享,只要有人为数据加入了写锁,其他人就不能为数据加任何锁.
select... from .... for update select * from table for update (写锁、排它锁)
乐观锁:丢失更新肯定不会发生
在表中提供一个字段(版本字段),用于标识记录。如果版本不一致,不允许操作。
hibernate处理丢失更新
悲观锁:写锁
![](https://i-blog.csdnimg.cn/blog_migrate/0f7112711b4ff824d89fb8d88464ec86.png)
package com.hcx.e_api;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.LockOptions;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
import com.hcx.domain.Customer;
import com.hcx.utils.HibernateUtils;
public class Demo2 {
@Test
//悲观锁
//写锁
public void fun1(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
Customer c
= (Customer) session.get(Customer.class, 1, LockOptions.UPGRADE);
System.out.println(c);
//------------------------------------------------
session.getTransaction().commit();
session.close(); // 游离状态
}
@Test
//悲观锁
//读锁
public void fun2(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
Customer c
= (Customer) session.get(Customer.class, 1, LockOptions.READ);
System.out.println(c);
//------------------------------------------------
session.getTransaction().commit();
session.close(); // 游离状态
}
}
@Test
public void demo01(){
//1 查询所有
Session session = factory.openSession();
session.beginTransaction();
Customer customer = (Customer) session.get(Customer.class, 1 ,LockMode.UPGRADE);
System.out.println(customer);
session.getTransaction().commit();
session.close();
}
乐观锁:
在PO对象(javabean)提供字段,表示版本字段。一般Integer
在*.hbm.xml 文件配置 <version name="...">
步骤一:在实体中加一个属性(提供get和set)
步骤二:在hbm.xml中设置
<!-- 告诉Hibernate , 乐观锁的版本号的属性名 -->
<version name="version"></version>
步骤三:测试
@Test
public void demo02(){
//1 查询所有
Session session = factory.openSession();
session.beginTransaction();
// Order order = new Order();
// order.setPrice(998d);
// session.save(order);
Order order = (Order) session.get(Order.class, 32);
order.setPrice(889d);
session.getTransaction().commit();
session.close();
}
case:
package com.hcx.e_api;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.LockOptions;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
import com.hcx.domain.Customer;
import com.hcx.utils.HibernateUtils;
public class Demo3 {
@Test
//乐观锁
public void fun1(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
Customer c
= (Customer) session.get(Customer.class, 1);
c.setName("tom");
System.out.println(c);
//------------------------------------------------
session.getTransaction().commit();
session.close(); // 游离状态
}
@Test
//悲观锁
//读锁
public void fun2(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
Customer c
= (Customer) session.get(Customer.class, 1, LockOptions.READ);
System.out.println(c);
//------------------------------------------------
session.getTransaction().commit();
session.close(); // 游离状态
}
}