如果你没有同一个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的更多相关文章

  1. android4.0以上访问网络不能在主线程中进行以及在线程中操作UI的解决方法

    MONO 调用一个线程操作UI 然后报Only the original thread that created a view hierarchy can touch its views.错误 goo ...

  2. Android中不能在子线程中更新View视图的原因

    这是一条规律,很多coder知道,但原因是什么呢? 如下: When a process is created for your application, its main thread is ded ...

  3. Python进阶(3)_进程与线程中的lock(线程中互斥锁、递归锁、信号量、Event对象、队列queue)

    1.同步锁 (Lock) 当全局资源(counter)被抢占的情况,问题产生的原因就是没有控制多个线程对同一资源的访问,对数据造成破坏,使得线程运行的结果不可预期.这种现象称为“线程不安全”.在开发过 ...

  4. 事务的隔离级别,mysql中开启事务、django中开启事务

    目录 一.事务的特性 二.数据库中开启事务 三.Django中开启事务的两种方式 第一种 第二种 四.事务的隔离级别 隔离级别 如何查看mysql隔离级别? 修改事务的隔离级别 隔离级别解释 read ...

  5. spring中涉及事务(bean中ref与local)

    <bean id="接口" parent="父id"> <property name="target"> <r ...

  6. 代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性

    做人事档案的系统考虑到数据的安全性与一致性,毕竟是要对外上线.真正投入使用的项目,数据库的可靠性与安全性上我们开发人员要考虑的就很多了,记得做机房收费系统时注册新卡是自己为了简单,写成了一个存储过程( ...

  7. 数据库事务及其EF中如何处理事务

    一.基础知识 1)         使用事务级别ReadUnCommited 会产生脏读现像,意味着读取到的为UnCommited(未提交)的数据.怎么理解呢?在使用该隔离级别的事务开始后.更新了数据 ...

  8. Spring 中的事务

    前言: 之前总结了事务以及数据库中事务相关的知识点,Spring 对于事务做了相应的封装,便于业务开发中使用事务. 项目中使用Spring中的事务首先时基于Mysql数据库中InnoDB 引擎的,如果 ...

  9. ASP.NET Core 新建线程中使用依赖注入的问题

    问题来自博问的一个提问 .net core 多线程数据保存的时候DbContext被释放 . TCPService 通过构造函数注入了 ContentService , ContentService ...

  10. Android Handler机制 (一个Thead中可以建立多个Hander,通过msg.target保证MessageQueue中的每个msg交由发送message的handler进行处理 ,但是 每个线程中最多只有一个Looper,肯定也就一个MessageQuque)

    转载自http://blog.csdn.net/stonecao/article/details/6417364 在android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长 ...

随机推荐

  1. Git婴幼儿使用手册【十分钟让你帅气的使用命令行和团队工作】

    Git由来:...... Git使用的好处:...... 如何使用Git:(以上会显得我们以下的是很纯纯的干货) 代码库有两个部分: 本地代码库:远程代码库: 本地代码库使用方法: 一.先创建一个文件 ...

  2. js时间操作getTime(),ios移动端真机上返回显示NAN

    ios移动端,js时间操作getTime(),getFullYear()等返回显示NaN的解决办法及原因 在做移动端时间转化为时间戳时,遇到了一个问题,安卓手机上访问时,能拿到时间戳,从而正确转换时间 ...

  3. java基础之二维数组-杨辉三角

    首先呢你要知道什么是杨辉三角? 答:杨辉三角,是二项式系数在三角形中的一种几何排列. 简单的说一下就是两个未知数和的幂次方运算后的系数问题,比如(x+y)的平方=x的平方+2xy+y的平方,这样系数就 ...

  4. Python学习day34-面向对象和网络编程总结

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  5. C#获取MP3,WMA信息

    用于获取MP3内部信息,包括歌曲名,歌手名等…… namespace FileBatchRemaer.domain { /// <summary> /// Mp3信息结构 /// < ...

  6. 给java mongodb 官方driver 增加bean 操作

      mongodb官方的java driver不支持直接插入java bean,只能使用DbObject的Key,Value形式进行insert,update,(c# mongodb官方driver类 ...

  7. SprigBoot中的 WebMvcConfigurer与 WebMvcConfigurerAdapter和 WebMvcConfigurationSupport

    WebMvcConfigurationAdapter 过时? 在SpringBoot2.0之后的版本中WebMvcConfigurerAdapter过时了,所以我们一般采用的是如下的两种的解决的方法. ...

  8. [转]C#设计模式(8)-Builder Pattern

    一. 建造者(Builder)模式 建造者模式可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象. 对象性质的建造 有些情况下,一个对象会有一些重 ...

  9. mysql基础教程(二)-----分组函数、多表查询、常见函数

    分组函数 什么是分组函数 分组函数作用于一组数据,并对一组数据返回一个值. 组函数类型 • AVG() • COUNT() • MAX() • MIN() • SUM() 组函数语法 AVG(平均值) ...

  10. [转载] DSP6000图像位移与变形典型算法

    原文地址:转载:DSP6000图像位移与变形典型算法作者:Jane 李现路:DSP6000图像位移与变形典型算法 一.图像的平移算法 图像平移的数学表达式原理: 初始坐标为(x0,y0)的点经过平移( ...