ibatis.net 多线程的调试
ibatis是一个挺不错的半自动orm框架,从java移植到c#
在ibatis中是支持多线程操作的,但是这几天的使用过程中发现就框架本身任然存在一些问题,可能会让你对多线程的使用并不是那么的顺利
在我们查询了ibatis的帮助手册后,不难找到这样一段内容

由此我们可以知道在使用sqlmapper时,我们对sqlmapper.sessionstore进行初始化HybridWebThreadSessionStore便可以进行多线程的使用,原理是什么呢?让我们下面来进行分析
首先ibatis定义了ISqlMapper接口,在接口中定义了一系列的数据库操作,ibaits本身给出了ISqlmapper接口的实现SqlMapper。
在我们的代码中,我们仅仅需要调用SqlMapper的方法即可完成对数据库的各种DML、DQL操作
看一下SqlMapper的初始化我们会发现
public SqlMapper(IObjectFactory objectFactory,
AccessorFactory accessorFactory)
{
_typeHandlerFactory = new TypeHandlerFactory();
_dbHelperParameterCache = new DBHelperParameterCache();
_objectFactory = objectFactory;
_accessorFactory = accessorFactory; _dataExchangeFactory = new DataExchangeFactory(_typeHandlerFactory, _objectFactory, accessorFactory);
_id = HashCodeProvider.GetIdentityHashCode(this).ToString();
_sessionStore = SessionStoreFactory.GetSessionStore(_id);
}
在第11行代码进行了_sessionStore 的复制,跟踪代码进入GetSessionStore方法
static public ISessionStore GetSessionStore(string sqlMapperId)
{
if (System.Web.HttpContext.Current == null)
{
return new CallContextSessionStore(sqlMapperId);
}
else
{
return new WebSessionStore(sqlMapperId);
}
}
可以很容易判断出当System.Web.HttpContext.Current为null时候通过CallContextSessionStore方法获取sessionstore,反之则通过WebSessionStore获取
这里我们总结一下,其实sqlmapper的_sessionStore 类型为ISessionStore,而前面根据帮助文档我们知道的HybridWebThreadSessionStore类以及GetSessionStore方法中提到的CallContextSessionStore类、WebSessionStore类都是对抽象类AbstractSessionStore的继承,而AbstractSessionStore抽象类则是对ISessionStore的实现,这样我们知道这里所有的动作其实都是对_sessionStore 赋值,至于具体使用哪一个实现类是根据情景的不同而初始化不同的实现类,不难发现,其实是ibatis在这里采用策略模式的实现方式。
这个时候我们来看一下从ISessionStore到具体的三个实现类中的代码
首先是ISessionStore接口代码
public interface ISessionStore
{
/// <summary>
/// Get the local session
/// </summary>
ISqlMapSession LocalSession
{
get;
} /// <summary>
/// Store the specified session.
/// </summary>
/// <param name="session">The session to store</param>
void Store(ISqlMapSession session); /// <summary>
/// Remove the local session from the storage.
/// </summary>
void Dispose();
}
可以看到在6-9行,这里的ISqlMapSession即是我们需要了解的核心,不同的实现类对该属性的返回采用了不同的方式
CallContextSessionStore
public override ISqlMapSession LocalSession
{
get { return CallContext.GetData(sessionName) as SqlMapSession; }
}
WebSessionStore
public override ISqlMapSession LocalSession
{
get
{
HttpContext currentContext = ObtainSessionContext();
return currentContext.Items[sessionName] as SqlMapSession;
}
}
HybridWebThreadSessionStore
public override ISqlMapSession LocalSession
{
get
{
HttpContext currentContext = HttpContext.Current;
if (currentContext == null)
{
return CallContext.GetData(sessionName) as SqlMapSession;
}
return currentContext.Items[sessionName] as SqlMapSession;
}
}
下面我们着重分析WebSessionStore的实现方式,由于在初始化实现类的过程判断中,我们不难发现当System.Web.HttpContext.Current不为null时,选择通过WebSessionStore来进行实例化,而WebSessionStore中的LocalSession属性我们可以看到直接通过HttpContext currentContext = ObtainSessionContext();对currentContext 进行赋值,跟踪ObtainSessionContext方法
private static HttpContext ObtainSessionContext()
{
HttpContext currentContext = HttpContext.Current;
if (currentContext == null)
{
throw new IBatisNetException("WebSessionStore: Could not obtain reference to HttpContext");
}
return currentContext;
}
终于找到了WebSessionStore: Could not obtain reference to HttpContext异常的来源,很奇怪的是在之前的实例化的过程中我们其实已经对HttpContext.Current进行过判断,这里怎么会出现为null的情况呢?
有这个疑问的话具体可以查看http://www.cnblogs.com/fish-li/archive/2013/04/06/3002940.html这里就不作详细的解释了
好了,问题终于找到了,下面就是如何去解决该问题,按照文档的说法是在使用sqlMap时通过sqlMap.SessionStore = new IBatisNet.DataMapper.SessionStore.HybridWebThreadSessionStore(sqlMap.Id);直接对SessionStore 进行赋值,但是问题来了,通过这样的方式在后面我们会发现还是会走到WebSessionStore中出现WebSessionStore: Could not obtain reference to HttpContext的异常,所以我在看了源码之后,发现其实WebSessionStore仅仅只是从currentContext.Items[sessionName]获取已经存储的SessionStore ,这样就好办了,于是我通过修改源码的方式彻底解决了这个问题
static public ISessionStore GetSessionStore(string sqlMapperId)
{
if (System.Web.HttpContext.Current == null)
{
return new CallContextSessionStore(sqlMapperId);
}
else
{
//return new WebSessionStore(sqlMapperId);
return new HybridWebThreadSessionStore(sqlMapperId);
}
}

ibatis.net 多线程的调试的更多相关文章
- 调试多线程 & 查死锁的bug & gcore命令 & gdb对多线程的调试 & gcore & pstack & 调试常用命令
gdb thread apply all bt 如果你发现有那么几个栈停在 pthread_wait 或者类似调用上,大致就可以得出结论:就是它们几个儿女情长,耽误了整个进程. 注意gdb的版本要高于 ...
- 多进程多线程GDB调试 (转)
多进程多线程GDB调试 一.线程调试指南: 1. gdb attach pid 挂载到调试进程 2. gdb$ set scheduler-locking on 只执行当前选定线程的 ...
- linux下多线程的调试
多线程调试的基本命令(均在gdb命令行使用): info threads ---- 显示当前可调试的全部线程.每个线程都有自己的线程ID,显示结果中前面有*的表示当前调试的线程. eg: ...
- [skill][gdb] gdb 多线程调试
中文快速入门: http://coolshell.cn/articles/3643.html (关于多线程的部署说的并不太对) 进阶: 多进程相关概念: inferiors 是什么? http://m ...
- GDB多线程调试
一.多线程调试1. 多线程调试,最重要的几个命令:info threads 查看当前进程的线程. ...
- 使用gdb调试多线程程序总结
转:使用gdb调试多线程程序总结 一直对GDB多线程调试接触不多,最近因为工作有了一些接触,简单作点记录吧. 先介绍一下GDB多线程调试的基本命令. info threads 显示当前可调试的所有线程 ...
- Debugging with GDB 用GDB调试多线程程序
Debugging with GDB http://www.delorie.com/gnu/docs/gdb/gdb_25.html GDB调试多线程程序总结 一直对GDB多线程调试接触不多,最近因为 ...
- gdb调试多线程程序总结
阿里核心系统团队博客 http://csrd.aliapp.com/?tag=pstack Linux下多线程查看工具(pstree.ps.pstack) http://www.cnblogs.com ...
- GDB 调试多线程多进程
GDB是linux下的调试利器,在c/c++程序开发过程中必不可少的.这里总结一下多进程和多线程的调试方法和技巧. 多进程的调试: 如下示例 #include <sys/mman.h> # ...
随机推荐
- [转]MyEclipse for Spring2014破解
转至:http://blog.my-eclipse.cn/myeclipse-2014-crack.html 一.安装完成MyEclipse2014(适用于2013等版本)后,不要打开软件,下载破解附 ...
- MFC拆分窗口及它们之间的数据交换(转)
转自:http://blog.csdn.net/nuptboyzhb/article/details/7455471 源代码:http://download.csdn.net/detail/nuptb ...
- mysql case when 条件过滤
[1].[代码] 使用CASE WHEN进行字符串替换处理 跳至 [1] [2] [3] [4] ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2 ...
- Thinkphp框架----微信公众测试号开发(2)
---恢复内容开始--- 最近忙着投简历找工作.现在继续更 微信回复图文设置. 效果: 页面HTML需要一个form表单 简单效果: 接下来是数据库 字段:id title(标题) text(描述) ...
- Node.js Crypto 加密算法库
Crypto库是随Nodejs内核一起打包发布的,主要提供了加密.解密.签名.验证等功能.Crypto利用OpenSSL库来实现它的加密技术,它提供OpenSSL中的一系列哈希方法,包括hmac.ci ...
- Vue2.0表单校验组件vee-validate的使用
vee-validate使用教程 *本文适合有一定Vue2.0基础的同学参考,根据项目的实际情况来使用,关于Vue的使用不做多余解释.本人也是一边学习一边使用,如果错误之处敬请批评指出* 一.安装 n ...
- 在DWZ框架中整合kindeditor复文本框控件
今天上午在DWZ框架中整合kindeditor复文本框控件,发现上传图片是老是提示 “上传中,请稍候...”,上网查看别人说可能是文件路径问题,在想以前在其他项目中用这个控件一直没问题,到这里怎么会出 ...
- java.io.File类
java.io.File类 1.凡是与输入.输出相关的类.接口等都定义在java.io包下 2.File是一个类.能够有构造器创建其对象.此对象相应着一个文件(.txt .avi .doc .ppt ...
- 关于Python中的self
虽然我现在写过一些Python代码,但实际上几乎还没用过Class,而且一直觉得一个很别扭的事情是,Class中的函数都要写个参数self,虽然实例化调用的时候不需要. 当然,一开始就知道Python ...
- delphi 插入表格HTML代码
<table width="174" height="76" border="1" align="center" ...