day36 11-Hibernate中的事务:当前线程中的session
如果你没有同一个session开启事务的话,那它两是一个独立的事务。必须是同一个session才有效。它给我们提供一个本地线程的session。这个session就保证了你是同一个session。其实它底层用的就是ThreadLocal。
什么是JTA事务?就是你底层操作的时候可能操作的不是同一个数据库。我们这里的保存都往同一个数据库里面保存。user和person都是保存到mysql数据库那不叫JTA事务,如果user保存到mysql数据库,person保存到oracle数据库,那这种事务的绑定用的是JTA这种事务,就是你操作的都不是同一个数据库了。SessionFactory.getCurrentSession()直接把当前线程中的session给它拿回去就行。只要是同一个线程就行,同一个线程拿的session肯定是同一个。SessionFactory.getCurrentSession()拿到当前线程绑定的session。只要是一个线程里面得到的都是同一个session。只不过当前线程中的session得配置一个值<property name="hibernate.current_session_context_class">thread</property>才可以使用。
package cn.itcast.utils; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; /**
* Hibernate抽取工具类
* @author 姜涛
*
*/
public class HibernateUtils {
private static Configuration configuration;
private static SessionFactory sessionFactory; static{
configuration = new Configuration().configure();
sessionFactory = configuration.buildSessionFactory();
} public static Session openSession(){
return sessionFactory.openSession();
}
public static Session getCurrentSession(){
return sessionFactory.getCurrentSession();//把当前线程中的session拿回去就行
}
public static void main(String[] args) {
openSession();
}
}
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
/*
* 当前线程这个绑定的session的使用
*
*/
public void demo8(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); Customer customer = new Customer();
customer.setCname("张三");
customer.setAge(28);
session.save(customer); tx.commit();
//session.close(); }
@Test
/*
* 事务通常在service层开启.session在DAO层.
* * 事务开启由session开启.
*
*/
public void demo7(){//hibernate做的是dao层的代码
Session session1 = HibernateUtils.openSession();
Session session2 = HibernateUtils.openSession();
System.out.println(session1==session2);
Session session3 = HibernateUtils.getCurrentSession();
Session session4 = HibernateUtils.getCurrentSession();
System.out.println(session3 == session4);
}
@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();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration>
<session-factory>
<!-- 必须去配置的属性 -->
<!-- 配置数据库连接的基本信息: -->
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url"><!-- 连接的数据库是hibernate3_day02 -->
jdbc:mysql:///hibernate3_day03
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<!-- Hibernate的方言 -->
<!-- 生成底层SQL不同的 -->
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property> <!-- 可选的属性 -->
<!-- 显示SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL -->
<property name="hibernate.format_sql">true</property> <property name="hibernate.connection.autocommit">false</property>
<!-- hbm:映射 to DDL: create drop alter -->
<property name="hibernate.hbm2ddl.auto">update</property> <!-- C3P0连接池设定-->
<!-- 使用c3po连接池 配置连接池提供的供应商-->
<property name="connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property> <!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property> <!--
1-Read uncommited isolation
2-Read commmitted isolation oracle默认是2
4-Repeatable read isolation mysql默认是4
8-Serializable isolation
-->
<property name="hibernate.connection.isiolation">4</property> <!-- 通知Hibernate加载那些映射文件 -->
<!-- <mapping resource="cn/itcast/hibernate3/demo1/Book.hbm.xml" />
<mapping resource="cn/itcast/hibernate3/demo2/Customer.hbm.xml" />
<mapping resource="cn/itcast/hibernate3/demo2/Order.hbm.xml" />
<mapping resource="cn/itcast/hibernate3/demo1/Book.hbm.xml" /> -->
<!-- 使用当前线程中的session -->
<property name="hibernate.current_session_context_class">thread</property><!-- 代表了当前线程中的session -->
<!-- 把映射文件中的这几个都拿掉 重新把它引入 -->
<mapping resource="cn/itcast/vo/Customer.hbm.xml" />
<mapping resource="cn/itcast/vo/Order.hbm.xml" /> </session-factory>
</hibernate-configuration>
day36 11-Hibernate中的事务:当前线程中的session的更多相关文章
- android4.0以上访问网络不能在主线程中进行以及在线程中操作UI的解决方法
MONO 调用一个线程操作UI 然后报Only the original thread that created a view hierarchy can touch its views.错误 goo ...
- Android中不能在子线程中更新View视图的原因
这是一条规律,很多coder知道,但原因是什么呢? 如下: When a process is created for your application, its main thread is ded ...
- Python进阶(3)_进程与线程中的lock(线程中互斥锁、递归锁、信号量、Event对象、队列queue)
1.同步锁 (Lock) 当全局资源(counter)被抢占的情况,问题产生的原因就是没有控制多个线程对同一资源的访问,对数据造成破坏,使得线程运行的结果不可预期.这种现象称为“线程不安全”.在开发过 ...
- 事务的隔离级别,mysql中开启事务、django中开启事务
目录 一.事务的特性 二.数据库中开启事务 三.Django中开启事务的两种方式 第一种 第二种 四.事务的隔离级别 隔离级别 如何查看mysql隔离级别? 修改事务的隔离级别 隔离级别解释 read ...
- spring中涉及事务(bean中ref与local)
<bean id="接口" parent="父id"> <property name="target"> <r ...
- 代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性
做人事档案的系统考虑到数据的安全性与一致性,毕竟是要对外上线.真正投入使用的项目,数据库的可靠性与安全性上我们开发人员要考虑的就很多了,记得做机房收费系统时注册新卡是自己为了简单,写成了一个存储过程( ...
- 数据库事务及其EF中如何处理事务
一.基础知识 1) 使用事务级别ReadUnCommited 会产生脏读现像,意味着读取到的为UnCommited(未提交)的数据.怎么理解呢?在使用该隔离级别的事务开始后.更新了数据 ...
- Spring 中的事务
前言: 之前总结了事务以及数据库中事务相关的知识点,Spring 对于事务做了相应的封装,便于业务开发中使用事务. 项目中使用Spring中的事务首先时基于Mysql数据库中InnoDB 引擎的,如果 ...
- ASP.NET Core 新建线程中使用依赖注入的问题
问题来自博问的一个提问 .net core 多线程数据保存的时候DbContext被释放 . TCPService 通过构造函数注入了 ContentService , ContentService ...
- Android Handler机制 (一个Thead中可以建立多个Hander,通过msg.target保证MessageQueue中的每个msg交由发送message的handler进行处理 ,但是 每个线程中最多只有一个Looper,肯定也就一个MessageQuque)
转载自http://blog.csdn.net/stonecao/article/details/6417364 在android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长 ...
随机推荐
- JavaScript中数组的基础知识和相关方法
数组基础 数组是大多数语言里面最常见的一种数据结构,它是一个有序的值列表. 创建数组 1.创建字面量数组 let arr=[]; 2.创建构造函数数组 let arr=new Array(); 注 ...
- 隐藏/显示jeecg-boot 后端管理页面的右侧的系统设置
登录后台,通过添加一个下拉选项[系统设置]来控制系统的后侧系统设置,布局如下: 修改UserMenu.vue文件 1.全局搜索“账户设置”,找到对应的vue文件:UserMenu.vue 2.添加[系 ...
- DevOps理论+实践之路
DevOps理论+实践之路 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大家看的时候可以关注 ...
- 轻量级IoC框架Ninject.NET搭建
说在之前的话 IOC的概念相信大家比较熟悉了,习惯性称之为依赖注入或控制反转,园子里对基于MVC平台IOC设计模式已经相当多了,但大家都只知道应该怎么应用一个IOC模式,比如Ninject, Unit ...
- [Bzoj3743][Coci2015] Kamp【换根Dp】
Online Judge:Bzoj3743 Label:换根Dp,维护最长/次长链 题目描述 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的 ...
- Leetcode953. Verifying an Alien Dictionary验证外星语词典
某种外星语也使用英文小写字母,但可能顺序 order 不同.字母表的顺序(order)是一些小写字母的排列. 给定一组用外星语书写的单词 words,以及其字母表的顺序 order,只有当给定的单词在 ...
- IDEA2018激活码
请复制如下内容到文本编辑器(如notepad++)把博客的内容去掉 N757JE0KCT-eyJsaWNlbnNlSWQiOiJONzU3SkUwS0NUIiwibGljZW5zZWVOYW1lIjo ...
- 威胁快报|Solr dataimport成挖矿团伙新型利用方式
概述 近日,阿里云安全团队监测到挖矿团伙利用solr dataimport RCE(CVE-2019-0193)作为新的攻击方式对云上主机进行攻击,攻击成功后下载门罗币挖矿程序进行牟利.该团伙使用的恶 ...
- typeof, offsetof, container_of宏
container_of宏实现如下: #define container_of(ptr, type, member) ({ \ )->member ) *__mptr = (ptr); \ (t ...
- linux负载均衡(什么是负载均衡)
linux负载均衡(什么是负载均衡) 一.总结 一句话总结: 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽.增加吞吐量.加强网络数据处理能力.提高网络的灵活性和可用 ...