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,使用它,我们可以在完成一个很长 ...
随机推荐
- 菜鸟nginx源码剖析数据结构篇(十) 自旋锁ngx_spinlock[转]
菜鸟nginx源码剖析数据结构篇(十) 自旋锁ngx_spinlock Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csd ...
- opencv-VS2010配置opencv2.4.8
详细教程可参考:http://blog.csdn.net/huang9012/article/details/21811129/ 原文在这里:[OpenCV入门教程之一] 安装OpenCV:OpenC ...
- Android基础控件ScrollView滚动条的使用
1.简介 ScrollView是一个FrameLayout的容器,不过在他的基础上添加了滚动,允许显示的比实际多的内容!另外,只能够往里面放置一个子元素,可以是单一的组件,又或者一个布局包裹着的复杂的 ...
- python collections模块 之 ChainMap
ChainMap提供了一种多个字典整合的方式,它没有去合并这些字典,而是将这些字典放在一个 maps (一个列表)里,内部实现了很多 dict 的方法,大部分 dict 的方法,ChainMap 都能 ...
- 2018-12-21-WPF-弹出-popup-里面的-TextBox-无法输入汉字
title author date CreateTime categories WPF 弹出 popup 里面的 TextBox 无法输入汉字 lindexi 2018-12-21 18:10:30 ...
- [转]WPF中Binding的技巧
在WPF应用的开发过程中Binding是一个非常重要的部分. 在实际开发过程中Binding的不同种写法达到的效果相同但事实是存在很大区别的. 这里将实际中碰到过的问题做下汇总记录和理解. 1. so ...
- object and namespace
http://effbot.org/zone/python-objects.htm 几点总结: (1) 类的基本属性 . id, returned by id(obj) . type, returne ...
- C动态分配内存
malloc分配内存时不初始化,calloc分配内存并进行初始化.
- 19-10-18-Night-U
话说T3: 一句话题意……见过这个嘛…… 于是:$\sum \limits_{i!=j} \binom{a_i+b_i+a_j+b_j}{a_i+a_j}$ ------------前言结束----- ...
- PHP实现微信退款的分析与源码实现
原文:https://blog.csdn.net/jason19905/article/details/78628349 网上的很多PHP微信支付接入教程都颇为复杂,且需要配置和引入较多的文件,本人通 ...