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 多线程的调试的更多相关文章

  1. 调试多线程 & 查死锁的bug & gcore命令 & gdb对多线程的调试 & gcore & pstack & 调试常用命令

    gdb thread apply all bt 如果你发现有那么几个栈停在 pthread_wait 或者类似调用上,大致就可以得出结论:就是它们几个儿女情长,耽误了整个进程. 注意gdb的版本要高于 ...

  2. 多进程多线程GDB调试 (转)

        多进程多线程GDB调试   一.线程调试指南:   1. gdb attach pid 挂载到调试进程  2. gdb$ set scheduler-locking on 只执行当前选定线程的 ...

  3. linux下多线程的调试

    多线程调试的基本命令(均在gdb命令行使用):    info threads ---- 显示当前可调试的全部线程.每个线程都有自己的线程ID,显示结果中前面有*的表示当前调试的线程.    eg: ...

  4. [skill][gdb] gdb 多线程调试

    中文快速入门: http://coolshell.cn/articles/3643.html (关于多线程的部署说的并不太对) 进阶: 多进程相关概念: inferiors 是什么? http://m ...

  5. GDB多线程调试

    一.多线程调试1. 多线程调试,最重要的几个命令:info threads                        查看当前进程的线程.                              ...

  6. 使用gdb调试多线程程序总结

    转:使用gdb调试多线程程序总结 一直对GDB多线程调试接触不多,最近因为工作有了一些接触,简单作点记录吧. 先介绍一下GDB多线程调试的基本命令. info threads 显示当前可调试的所有线程 ...

  7. Debugging with GDB 用GDB调试多线程程序

    Debugging with GDB http://www.delorie.com/gnu/docs/gdb/gdb_25.html GDB调试多线程程序总结 一直对GDB多线程调试接触不多,最近因为 ...

  8. gdb调试多线程程序总结

    阿里核心系统团队博客 http://csrd.aliapp.com/?tag=pstack Linux下多线程查看工具(pstree.ps.pstack) http://www.cnblogs.com ...

  9. GDB 调试多线程多进程

    GDB是linux下的调试利器,在c/c++程序开发过程中必不可少的.这里总结一下多进程和多线程的调试方法和技巧. 多进程的调试: 如下示例 #include <sys/mman.h> # ...

随机推荐

  1. HDU 3577 Fast Arrangement (线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3577 题意不好理解,给你数字k表示这里车最多同时坐k个人,然后有q个询问,每个询问是每个人的上车和下车 ...

  2. ags注册

    在电脑里找到2个 ESRIRegAsm.exe C:\Program Files (x86)\Common Files\ArcGIS\bin C:\Program Files\Common Files ...

  3. android ipc通信机制之二序列化接口和Binder

    IPC的一些基本概念,Serializable接口,Parcelable接口,以及Binder.此核心为最后的IBookManager.java类!!! Serializable接口,Parcelab ...

  4. Unix: How to Install BerkeleyDB From Source

    http://www.masaokitamura.com/2010/07/23/unix-how-to-install-berkeleydb-from-source/ This documentati ...

  5. 使用Unity制作游戏关卡的教程(一)

    转自: http://gamerboom.com/archives/74131 作者:Matthias Zarzecki 我正在制作<Looking For Group – The Fork O ...

  6. 在Web上调用Ocx控件

    原文:http://blog.csdn.net/goodadult2012/article/details/6343369 在HTML页面中使用ActiveX控件包含三个基本操作:将控件放入HTML中 ...

  7. 设计一个算法,输出从u到v的全部最短路径(採用邻接表存储)

    思想:用path数组存放路径(初始为空),d表示路径长度(初始为-1),查找从顶点u到v的最短路径过程如图所看到的: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5u ...

  8. cocos2d粒子效果

    第9章 粒子效果 游戏开发者通常使用粒子系统来制作视觉特效.粒子系统能够发射大量细小的粒子并对他们进行渲染,而且效率要远高于渲染同样数目的精灵.粒子系统可以模拟下雨.火焰.雪.爆炸.蒸气拖尾以及其他多 ...

  9. NGUI panel使用soft clip时,屏幕缩放后无法正常工作的问题解决

    最近开始使用NGUI,通过查找,搞定了屏幕缩放问题,但在用到panel的soft clip时,碰到了问题,NGUI给出了警告 “clipped panels must have a uniform s ...

  10. 高级I/O之异步I/O

    A synchronous I/O operation causes the requesting process to be blocked until that I/O operation com ...