关于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('/ ...
随机推荐
- tracef 安装 跟踪 函数调用图
http://www.prevanders.net/dwarf.html redhat 5.4 tar -zxvf libdwarf-20140519.tar.gz [root@localhost d ...
- IE中Ext的comboBox跑到页面左上角
{ xtype:'combo', width:100, //id:'exTypeCom', name:'exType', hiddenName:'exType', displayField:'text ...
- extjs表单验证
extjs表单验证 //放在onReady的function(){}中 Ext.QuickTips.init(); //为组件提供提示信息功能,form的主要提示信息就是客户端验证的错误信息. Ext ...
- .NET:CLR via C# User-Mode Constructs
The CLR guarantees that reads and writes to variables of the following data types are atomic: Boolea ...
- WebLogic Server 12c相对JBoss EAP 6的优势
原文来自:https://blogs.oracle.com/middlewareplace/entry/why_should_you_choose_oracle 1.多数据中心部署和集群 WebLog ...
- [翻译] 5点建议,让iOS程序跑得更快
[文章原地址]http://mobile.tutsplus.com/tutorials/iphone/ios-quick-tip-5-tips-to-increase-app-performanc ...
- Spring与web MVC的整合——Spring的应用上下文管理
问题1 如何让web容器加载你的web MVC框架 对于基于servlet的web容器来说,遵循的是servlet规范,入口配置文件是web.xml.这类web容器会在启动的时候会而且仅会加载如下三种 ...
- C语言存储类型
看c专家编程,有说存储类型一直不太清楚.看到一篇文章讲解c的存储类型,讲解了c语言中的各种变量的存储类型,而且是从进程.内存的角度讲解的,以前从没有这样理解过,觉得挺有用的,在这里转载过来. 首先要来 ...
- Multi-label && Multi-label classification
Multi-label classification with Keras In today’s blog post you learned how to perform multi-label cl ...
- 输错密码?这个 sudo 会“嘲讽”你
导读 你在 Linux 终端中会有很多的乐趣.我今天要讲的不是在终端中跑火车.我今天要讲的技巧可以放松你的心情.你学习过如何在命令行中增加 sudo 命令的超时,今天的文章中,我会向你展示如何让 su ...