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> # ...
随机推荐
- 强连通分量(tarjan求强连通分量)
双DFS方法就是正dfs扫一遍,然后将边反向dfs扫一遍.<挑战程序设计>上有说明. 双dfs代码: #include <iostream> #include <cstd ...
- linux 查看当前所在目录的全路径
有时候,使用linux的shell的时候需要查看当前位置的全路径,可以使用 pwd命令 当然,知道了该命令就可以通过man pwd来查看该命令的全部帮助手册.
- 树莓派加入定时任务实现花生壳定时重启(linux的定时任务)
由于花生壳在linux下不稳定,联系开机一个星期左右会挂掉,所以要使用定时任务实现每小时刷新一次/启动一次. 使用的是linux下的定时任务crontab去实现. 实现步骤: 1.编辑/etc/cro ...
- zookeeper的配置项
1 tickTime:CS通信心跳数 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳.tickTime以毫秒为单位. tick ...
- [置顶] Jquery中DOM操作(详细)
Jquery中的DOM操作 为了能全面的讲解DOM操作,首先需要构建一个网页. HTML代码: <%@ page language="java" import="j ...
- 用 JavaScript 修改样式元素
利用 <style> 元素,我们可以在网页中嵌入样式表.如果需要动态增加 <style> 元素,似乎可以用如下的 JavaScript 代码: var style = docu ...
- CCBReader
#ifndef _CCB_CCBREADER_H_ #define _CCB_CCBREADER_H_ #include "cocos2d.h" #include "Ex ...
- 随意一条查询sql转换为查询结果集相应的数目
原思路: 像括号配对一样,假设遇见select 就入栈,假设遇见from就出栈,直到栈为空,取得此时的位置.进行字符串截取. 实现方法:遇见字符s而且连续后5个字符elect 就+1,遇见字符f而且连 ...
- openstack 创建虚拟机
http://blog.csdn.net/tantexian/article/details/44595885#comments
- 迷途指针 new delete
编程中有一种很难发现的错误是迷途指针.迷途指针也叫悬浮指针.失控指针,是党对一个指针进行delete操作后——这样会释放它所指向的内存——并没有把它设置为空时产生的.而后,如果你没有重新赋值就试图再次 ...