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> # ...
随机推荐
- FZU 2082 过路费 (树链剖分 修改单边权)
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2082 树链剖分模版题,求和,修改单边权. #include <iostream> #include ...
- HDU1028Ignatius and the Princess III(母函数)
http://acm.hdu.edu.cn/showproblem.php?pid=1028 母函数: 例1:若有1克.2克.3克.4克的砝码各一 枚,能称出哪几种重量?各有几种可能方案? 如何解决这 ...
- HDU 1796How many integers can you find(简单容斥定理)
How many integers can you find Time Limit: 12000/5000 MS (Java/Others) Memory Limit: 65536/32768 ...
- 集合引入(ArrayList、LinkedList)
1.引入 代替数组固定大小操作不变 2.ArrayList 常用的操作(add,remove) 3.LinkedList 能实现一些特殊的操作(pop)
- .Net 揭密--JIT怎样运行你的代码
方法调用: 第一部分 (普通调用) 译者:我们都知道.NET托管代码如C#.VB.NET写成的代码,都是先被编译成中间语言(IL,Intermediate Language,在运行时,再由即时编译器( ...
- shell脚本的入参
shell脚本参数可以任意多,但只有前9个可以被访问,使用shift命令可以改变这个限制.参数从第一个开始,在第九个结束.$0 程序名字$n 第n个参数值,n=1..9 $* 所有命令行参数$@ ...
- PostgreSQL的schema信息,存储于何处
查看schema信息: [pgsql@localhost bin]$ ./psql psql () Type "help" for help. pgsql=# create sch ...
- JAVA实现HTTPserver端
用java socket实现了一个简单的httpserver, 能够处理GET, POST,以及带一个附件的multipart类型的POST.尽管中途遇到了非常多问题, 只是通过在论坛和几个高手交流了 ...
- Codeforces gym 100685 C. Cinderella 水题
C. CinderellaTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100685/problem/C ...
- phpcms v9和discuz X3.1实现同步登陆退出论坛(已实现)
网络上文章很多,按步骤配置好了之后phpcms可以同步登录dz,但是dz登录后状态却无法同步到phpcms,网络上找了很多资料都大同小异,头大.只能自己调试了,废话不多说了. 以下网络上抄 ...