jforum事务与ThreadLocal

当前位置:

jforum事务与ThreadLocal

作者:邓华锋于2010-12-23发布在 分类:jforum / 阅读17119 次 / 共有0条评论  

jforum事务控制是粗粒度控制的,也就是说,对每个请求Service的线程,如果需要获得数据库连接,则
Java代码 
JForumExecutionContext ex = get();   
        Connection c =  ex.conn;   
           
        if (validate && c == null) {   
            c = DBConnection.getImplementation().getConnection();   
               
            try {   
                c.setAutoCommit(!SystemGlobals.getBoolValue(ConfigKeys.DATABASE_USE_TRANSACTIONS));   
            }   
            catch (Exception e) {   
                //catch error autocommit   
            }   
               
            ex.setConnection(c);   
            set(ex);   
        }  

JForumExecutionContext 是一个执行上下文,持有 connection引用。JForumExecutionContext对每个请求的线程都保存当前 线程的 执行上下文(JForumExecutionContext),每次需要数据库连接时,都从当前线程的本地变量中获得连接,当前线程中的数据库连接为空,就新建一个连接。如果系统配置了需要事务,则:
Java代码 
c.setAutoCommit(!SystemGlobals.getBoolValue(ConfigKeys.DATABASE_USE_TRANSACTIONS));  

在此处设置了连接是否 自动提交。
在每次使用完connection,不必关闭连接,而是程序统一在servlet 的Service方法中完成本次请求后释放资源,判断是否提交事务,并且关闭连接。

Java代码 
JForumExecutionContext.finish();  

finish实现如下:

Java代码 
public static void finish()   
    {   
        Connection conn = JForumExecutionContext.getConnection(false);   
           
        if (conn != null) {   
            if (SystemGlobals.getBoolValue(ConfigKeys.DATABASE_USE_TRANSACTIONS)) {   
                if (JForumExecutionContext.shouldRollback()) {   
                    try {   
                        conn.rollback();   
                    }   
                    catch (Exception e) {   
                        logger.error("Error while rolling back a transaction", e);   
                    }   
                }   
                else {   
                    try {   
                        conn.commit();   
                    }   
                    catch (Exception e) {   

                        logger.error("Error while commiting a transaction", e);   
                    }   
                }   
            }   
               
            try {   
                DBConnection.getImplementation().releaseConnection(conn);   
            }   
            catch (Exception e) {   
                logger.error("Error while releasing the connection : " + e, e);   
            }   
        }   
           
        userData.set(null);   
    }  

这样的实现,事务是控制住了,但是事务的跨度太大,粒度太粗,相反,spring的事务控制 就可以控制到比较细了。
spring声明式事务控制,通过aop,动态代理生成需要控制事务的类,并且注入事务拦截接口而实现的。在spring本地事务中,也是通过ThreadLocal 来持有对当前线程的获得的数据库连接的,使用ThreadLocal好处就是在任何地方都能访问当前线程保存在其中的数据,而不用担心多线程访问的问题,因为每个线程都只能访问当前线程对应的那部分数据。不过对分布式事务的实现而言,ThreadLocal 恐怕帮不上忙了,具体我也不是很清楚,下面请哪位看管讲讲。。。
 

  • 标签: jforum 事务 线程
  • 该日志于 2010-12-23 14:04 由 邓华锋 发表在 邓华锋 上,你除了可以发表评论外,还可以转载"jforum事务与ThreadLocal"日志到你的网站或博客,但是请保留源地址及作者信息,谢谢!!
  • 版权所有:《邓华锋》 => 《jforum事务与ThreadLocal
    本文地址:http://dhf.me/post-54.html
    除非注明,文章均为 《邓华锋》 原创,欢迎转载!转载请注明本文地址,谢谢。