关于NHibernate中存在于Session中实例的3种状态的简单分析
在使用NHibernate的时候。在Session中会有3种状态。
1. 瞬时状态 (Transient)
由 new 命令开辟内存空间的对象,也就是平时所熟悉的普通对象。
如: Student stu = new Student(); 瞬时对象特点:(1) 不和 Session 实例关联, 也就是说。在Session中没有缓存指向这个对象地址的引用; (2) 在数据库中没有和瞬时对象关联的记录。也就是说。这个对象的主键属性,在数据库中没有哪一行的主键与其相应。
2. 持久状态 (Persistent)
持久对象总是与 Session 和 Transaction 相关联,在一个 Session 中,对持久对象的改变不会立即对数据库进行变更,而必须在Transaction 终止,也就是执行 commit() 之后,才在数据库中真正执行 SQL 进行变更。持久对象的状态才会与数据库进行同步。在同步之前的持久对象称为脏 (dirty) 对象。瞬时对象转为持久对象:(1) 通过 Session 的 save() 和 saveOrUpdate()
方法把一个瞬时对象与数据库相关联。这个瞬时对象就成为持久化对象。
(2) 使用 fine(),get(),load() 和 iterater() 方法查询到的数据对象。将成为持久化对象。持久化对象的特点:(1) 和 Session 实例关联,而且在Session中有指向这个内存对象地址的引用 (2) 在数据库中有和持久对象关联的记录。
3. 脱管状态 (Detached)
与持久对象关联的 Session 被关闭后,对象就变为脱管对象。对脱管对象的引用依旧有效,对象可继续被改动。
脱管对象特点:(1) 本质上和瞬时对象同样。 仅仅是比瞬时对象多了一个数据库记录标识值 id. 注意这是数据库自增主键的情况。假设是assgin id情况。那么与瞬时对象可能就全然一样了。(2) 在数据库中有与其相应的记录。持久对象转为脱管对象:当运行 close() 或 clear(),evict() 之后,持久对象会变为脱管对象。
瞬时对象转为持久对象:通过 Session 的 update(),saveOrUpdate()
和 lock() 等方法,把脱管对象变为持久对象。
终于总结起来,就是要分析session缓存中的id,referrence键值对是否志向指定对象的问题。transient不指向,persistent指向,detached不指向,但与ransient不同的是,数据库中已经有了对象相应的记录。
关于Session一些方法的执行原理。
Session.save(user):1, 把User对象增加Session缓存中,使它变成持久化对象。此时并没有数据库中相应的记录,清理缓存后,把SQL语句同步到数据库。2. 选用映射文件指定的标识生成ID;3。在Session清理缓存时候运行:在底层生成一个insert sql语句,把对象存入数据库。
注意:在你运行Session.save(user)后。在Session清理缓存前,假设你改动user对象属性值。那么终于存入数据库的值将是最后改动的值;此过程中ID不能被改动;
Session.delete(user):假设user是持久化对象,则运行删除操作,相同底层数据库的运行条件是:在Session清理缓存时候;假设user是游离对象,将user对象和Session关联,使之成为持久化对象,所以这时候会发出select的SQL语句,这就是为什么你用NHibernate删除一个对象的时候。它会先发出select的语句。然后依照user 是持久化对象的过程运行。
Session.update(user):假设user是持久化对象。那么不进行不论什么操作,一切操作都是等到清空缓存的时候同步到数据库。假设user是游离对象。那么也是先转为持久对象。然后再等清理缓存的时候同步到数据库。所以Update的时候也会发出select语句。
Session.SaveOrUpdate(user):假设如今session中没有user的缓存,说明这是一个transient或者detached的对象,它会先向数据库发出select语句,注意select语句发出之前是会Flush缓存的,防止select到的是未更新的数据库内容。
发出select语句后,假设没有查询到不论什么内容,说明这是一个新的对象,transient的。这时会把这个transient的对象放入到session缓存中,成为persistent状态。这是在session中标记一下这个对象相应的是什么样的SQL操作,在终于Flush拼接SQL语句的时候,是insert还是update. 假设查询到了记录,说明这是一个detached的对象。这时会把这个对象放入到session缓存中,变成persistent状态。
最后,再调用session.Flush()的时候,会生成一些SQL语句,把这些内容同步到数据库中。假设如今session中有这个user对象所在地址的缓存,那么什么也不用做。Flush的时候同步到数据库就可以。
一种特别情况,假设session中没有这个对象的缓存,可是却有其它的某个对象缓存,有同一个id值存在,这是就会抛出异常。
Session 什么时候清理缓存,这是一个非常关键的问题。什么是缓存清理?就是缓存中主键key相应的内存中的对象与数据库中同主键的记录进行同步的过程,也就是与数据库发生了交互,全部内存中对象的变动都提交到了数据库,注意,并不一定永久性的保持到数据库,这要看是否transaction的提交。而且。session缓存中的id与对象引用也清除。
清理缓存的时机例如以下,1,commit() 方法被调用时 2,查询时会主动commit清理缓存。保证查询结果能反映对象的最新状态。3,显示的调用session 的 flush方法。
注意Session的commit()和flush()方法的差别,flush()方法进行清理缓存的操作,运行一系列的SQL语句,假设没有事务,则持久化到数据库。
假设是事务,尽管在数据库中运行了SQL,但不会提交事务。是能够回滚的。commit()方法先调用flush()。然后提交事务。
提交事务意味着对数据库所做的更新被永久保存下来。一般使用方法是Ssession.save(user);
Session.flush(); 当你调用save方法的时候,这个实体对象未必已经保存到数据库了,当你调用flush方法的时候是强制将对象保存到数据库。注意。强制保存到数据库的记录假设是在事务中的,也是能够回滚的。
比方说,Flush之后,你去数据库select。会发现这条记录已经存在。可是由于某些原因造成事务回滚了。代码运行完后你再去select。会发现那条记录已经不再了,由于已经回滚到插入之前状态了。
关于NHibernate中存在于Session中实例的3种状态的简单分析的更多相关文章
- thinkphp中cookie和session中操作数组的方法
thinkphp中cookie和session中操作数组的方法 一.ThinkPHP模板中如何操作session,以及如果session中保存的是数组的情况 在ThinkPHP的模板中操作sessio ...
- Java实现购物车功能:方式一:存放在session中.方式二:存储在数据库中
//将购物车产品加入到cookie中,方式同浏览记录.Java实现购物车,方式一(简易版):存储在session中.这种方式实现还不严谨,大家看的时候看思路即可.(1). JSP页面中,选择某一款产品 ...
- ArcGIS 开发时,解决__类型“XX”同时存在于“”和“”中__的错误
错误提示:类型“ESRI.ArcGIS.ADF.BaseClasses.BaseCommand”同时存在于“e:\Program Files\ArcGIS\DeveloperKit10.2\DotNe ...
- 在java中怎样实现多线程?线程的4种状态
一.在java中怎样实现多线程? extends Thread implement Runnable 方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 ...
- adt导入已经存在于workspace中的项目
场景: Eclipse中某android项目被delete,但是并未勾选“delete project contents from disk(cannot be undone)”.删除后,下次再想打开 ...
- 对于HTML页面中CSS, JS, HTML的加载与执行过程的简单分析
来自 https://blog.csdn.net/u011088260/article/details/79563315 最近在研究HTML页面中JavaScript的执行顺序问题.在Java ...
- 压测过程中,CPU和内存占用率很高,案例简单分析
Q: 最近公司测试一个接口,数据库采用Mongo 并发策略:并发400个用户,每3秒加载5个用户,持续运行30分钟 数据量:8000条左右 压测结果发现: TPS始终在5左右 ...
- MapReduce实例-NASA博客数据频度简单分析
环境: Hadoop1.x,CentOS6.5,三台虚拟机搭建的模拟分布式环境,gnuplot, 数据:http://ita.ee.lbl.gov/html/contrib/NASA-HTTP.htm ...
- Flask中cookie和session设置与csrf原理攻防
Flask之操作cookie app.py from flask import Flask, request, Response app = Flask(__name__) @app.route('/ ...
随机推荐
- Effective JavaScript Item 35 使用闭包来保存私有数据
本系列作为EffectiveJavaScript的读书笔记. JavaScript的对象系统从其语法上而言并不鼓舞使用信息隐藏(Information Hiding).由于当使用诸如this.name ...
- 线程系列07,使用lock语句块或Interlocked类型方法保证自增变量的数据同步
假设多个线程共享一个静态变量,如果让每个线程都执行相同的方法每次让静态变量自增1,这样的做法线程安全吗?能保证自增变量数据同步吗?本篇体验使用lock语句块和Interlocked类型方法保证自增变量 ...
- C#编程(三)
原文链接:http://blog.csdn.net/shanyongxu/article/details/46398713 C#中的常量 定义常量所需要的关键字:const,语法结果:const 变量 ...
- Entityframework:启用延时加载的主意事项(只为强化记忆)
Check List 无参的.高于私有访问级别的构造方法(经常忘记). 非封闭的类(默认的非封闭的). DbContext 配置要开启(默认是开启的). 因为我喜欢将类型设置为封闭的,提供有参数的构造 ...
- eclipse3.4配置的tomcat server如何部署以前的web项目?
1. 打开.project文件,在<natures>元素中加入 <nature>org.eclipse.wst.common.project.facet.core.nature ...
- 字符函数PATINDEX()与STUFF()
函数 PATINDEX() STUFF() 取数字 英语 汉字 更多:http://msdn.microsoft.com/zh-cn/library/ms188395.aspx PATINDEX() ...
- 如何使用Windows Library文件进行持久化
前言 想象一下,假设在你不知道的情况下,攻击者在你的计算机上放置了一个恶意文件.每当你访问桌面上某个文件夹时(例如Documents文件夹),都会执行一次该文件.这样的场景,通过利用一种鲜为人知的持久 ...
- super-pow
// https://discuss.leetcode.com/topic/50489/c-clean-and-short-solution class Solution { ; int powMod ...
- PHP json_encode转换空数组为对象
问题描述: php返回json格式的数据,当返回数据的为数组,且key为字符串时,json化后将返回jsonObject,但是如果是空数组,有可能返回的就是jsonArray,数据结构不一致导致端解析 ...
- 微信小程序开发:设置消息推送
开发设置中,启用并设置消息推送配置后,用户发给小程序的消息以及开发者需要的事件推送,都将被微信转发至该服务器地址中. 不过照着说明去操作,即使按照最简单的明文方式去设置,还是提示Token验证失败.仔 ...