在使用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种状态的简单分析的更多相关文章

  1. thinkphp中cookie和session中操作数组的方法

    thinkphp中cookie和session中操作数组的方法 一.ThinkPHP模板中如何操作session,以及如果session中保存的是数组的情况 在ThinkPHP的模板中操作sessio ...

  2. Java实现购物车功能:方式一:存放在session中.方式二:存储在数据库中

    //将购物车产品加入到cookie中,方式同浏览记录.Java实现购物车,方式一(简易版):存储在session中.这种方式实现还不严谨,大家看的时候看思路即可.(1). JSP页面中,选择某一款产品 ...

  3. ArcGIS 开发时,解决__类型“XX”同时存在于“”和“”中__的错误

    错误提示:类型“ESRI.ArcGIS.ADF.BaseClasses.BaseCommand”同时存在于“e:\Program Files\ArcGIS\DeveloperKit10.2\DotNe ...

  4. 在java中怎样实现多线程?线程的4种状态

    一.在java中怎样实现多线程? extends Thread implement Runnable 方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 ...

  5. adt导入已经存在于workspace中的项目

    场景: Eclipse中某android项目被delete,但是并未勾选“delete project contents from disk(cannot be undone)”.删除后,下次再想打开 ...

  6. 对于HTML页面中CSS, JS, HTML的加载与执行过程的简单分析

    来自   https://blog.csdn.net/u011088260/article/details/79563315   最近在研究HTML页面中JavaScript的执行顺序问题.在Java ...

  7. 压测过程中,CPU和内存占用率很高,案例简单分析

    Q:  最近公司测试一个接口,数据库采用Mongo    并发策略:并发400个用户,每3秒加载5个用户,持续运行30分钟    数据量:8000条左右 压测结果发现:    TPS始终在5左右   ...

  8. MapReduce实例-NASA博客数据频度简单分析

    环境: Hadoop1.x,CentOS6.5,三台虚拟机搭建的模拟分布式环境,gnuplot, 数据:http://ita.ee.lbl.gov/html/contrib/NASA-HTTP.htm ...

  9. Flask中cookie和session设置与csrf原理攻防

    Flask之操作cookie app.py from flask import Flask, request, Response app = Flask(__name__) @app.route('/ ...

随机推荐

  1. C#程序集系列03,引用多个module

    我们经常在项目中引用程序集.通常情况下,一个程序集包含一个module,但一个程序集也可以包含多个module.本篇就来体验:在一个可以被编译成.exe可执行文件的.cs文件中引用多个module. ...

  2. MVC使用Dotnet.HighCharts做图表01,区域图表

    如果想在MVC中使用图表显示的话,DotNet.HighCharts是不错的选择.DotNet.HighCharts是一个开源的JavaScript图表库,支持线型图表.柱状图标.饼状图标等几十种图标 ...

  3. 常用VPS测试工具整理

    来源: http://www.vpser.net/manage/vps-test-tool.html 购买VPS前主要是使用一些网络测试工具如ping.tracert.WinMTR之类的工具进行测试, ...

  4. 解决Arcgis10.2.2中dbf文件用EXCEL打开乱码问题

    1.开始 -- 运行,输入”Regedit“,打开 注册表 . 2.如是用的是 10.x 版本 ArcGIS Desktop,定位到 ‘计算机\HKEY_CURRENT_USER\Software\E ...

  5. C语言项目:学生成绩管理系统

    C语言项目:学生成绩管理系统    1.数据结构:学生信息:学号.姓名.年龄.性别.3课成绩    2.功能:   (1)增加学生记录    (2)  删除学生记录    (3)  查找学生信息(学号 ...

  6. C++ string 字符串查找匹配

    在写C++程序中,总会遇到要从一个字符串中查找一小段子字符串的情况,对于在C中,我们经常用到strstr()或者strchr()这两种方法.而对于C++的string,我们往往会用到find(). C ...

  7. Same Tree leetcode java

    题目: Given two binary trees, write a function to check if they are equal or not. Two binary trees are ...

  8. SoundPool 音频播放 API 详解【示例】

    demo地址:https://github.com/baiqiantao/PermissionTest.git 一个大坑:SoundPool最多只能播放时长10s左右.大小70kb左右(这些值是我多次 ...

  9. Loadrunner视频教程汇总

    小布老师视频:测试工具概述,兼LoadRunner介绍 -1-4http://www.boobooke.com/v/bbk1046http://www.boobooke.com/v/bbk1046.z ...

  10. 11个JavaScript颜色选择器插件

    几年前,很难找到一个合适的颜色选择器.正好看到很多不错的JavaScript颜色选择器插件,故而把这些编译汇总.在本文,Web设计师和开发人员 Kevin Liew 选取了11个相应插件,有些会比较复 ...