jforum事务与ThreadLocal

jforum事务控制是粗粒度控制的,也就是说,对每个请求Service的线程,如果需要获得数据库连接,则

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),每次需要数据库连接时,都从当前线程的本地变量中获得连接,当前线程中的数据库连接为空,就新建一个连接。如果系统配置了需要事务,则:

c.setAutoCommit(!SystemGlobals.getBoolValue(ConfigKeys.DATABASE_USE_TRANSACTIONS));

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


JForumExecutionContext.finish();

finish实现如下:


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 恐怕帮不上忙了,具体我也不是很清楚,下面请哪位看管讲讲。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值