jdbc一个connection 下的事务问题

哎呦-又忘了 发布于 2016/01/25 14:43
阅读 557
收藏 1

华为云11月刊推送:DIY微信问答机器人,高性能计算代码的20个技巧!>>>

在不分层的情况下,一个JDBC事务处理代码片断如下:

try {
    conn =DriverManager.getConnection("url","username","userpwd";
    conn.setAutoCommit(false);//禁止自动提交,设置回滚点
    stmt = conn.createStatement();
    stmt.executeUpdate("alter table …"); //数据库更新操作1
    stmt.executeUpdate("insert into table …"); //数据库更新操作2
    conn.commit(); //事务提交
}catch(Exception ex) {  
  ex.printStackTrace();
  try {
      conn.rollback(); //操作不成功则回滚
  }catch(Exception e) {
        e.printStackTrace();
    }
}

对目前的开发来说,基本都会采用分层的架构,如:表现action层、业务逻辑service层、数据访问dao层;
spring对事务做了很好的封装;但是在很多的需求和应用,jdbc还是有其优势的。所以,这里只讨论纯jdbc下分层架构的事务控制。

当采用分层架构的时候,jdbc事务的问题出在:
一 分层架构中,事务控制应该放在哪一层,我的意见: 
事务是以业务逻辑为基础的;一个完整的业务应该对应服务层里的一个方法;如果业务操作失败,则整个事务回滚;所以,事务控制是绝对应该放在service层的;
二 如果不同意第一条,认为事务控制可以放在DAO层中,请看下面的例子:
有一个班级业务逻辑类classService,对班级的删除操作,级联到另一张表班级学生关系表的记录删除。
想要将这两个操作放在一个事务中,你可以会这样设计ClassDAO:

public class ClassDAO {
        private Connection conn = DBManager.getConnection;
        public void delClassAndClassStuReal(String classId) {
            try {
                conn.setAutoCommit(false);
                //班级的删除
                //班级学生关系记录的删除
                conn.commit(); //事务提交
            } catch(SQLException e) {
                 try {
                         conn.rollback();
                 }
            }
            
        }
    }

但是,DAO层的设计应该遵循一个很重要的原则:DAO层应该保证操作的原子性,就是说DAO里的每个方法都应该是不可以分割的。基于DAO层设计的细粒度原则,classDAO中应该是有这样两个方法:

public class ClassDAO {
        public void delClass(String classId) {
            //班级的删除
        }
        public void delClassStuReals(String classId) {
            //班级学生关系记录的删除
        }
    }
那事务的问题就来了:怎样保证这两个删除操作的执行在同一个事务中?
三 如果你原则上同意第一条:
jdbc中事务控制是基于Connection的;虽说事务控制应该放在service层,但是Connection是不应该在service层中被实例出来的。一个有悖解耦的jdbc分层事务控制想法是:
在service层中实例Connection并控制事务;调用dao的时候将这个Connection传给dao层。
这样做,存在明显的耦合:dao层依赖了service层;我们做分层应该是上层依赖下层的,下层依赖上层是不应该出现的。

加载中
0
如比如比
如比如比
都用连接池了,有这么固定么,虽然是尽可能在db操作时使用事务,但由于BL过于复杂而出现db事务也无可厚非,也有在PL里开事务的,但有一点事务的处理经量短小,剩下的感觉能高效解决问题,方便维护就行了。
如比如比
如比如比
回复 @哎呦-又忘了 : bl侧重业务,pl侧重ui
哎呦-又忘了
哎呦-又忘了
菜鸟不懂 BL、 PL 是啥呀?
0
maradona
maradona
Connection放到ThreadLocal即可
0
f
fegaf

dao层只是依赖了service层的Connection,其他的不依赖,dao层可以根据Connection自定义sql语句,这就够了;

所谓的不依赖,不是所有都不依赖,比如面向接口编程,虽然对接口产生了依赖,但是实现类如何实现是自由的,这就够了,提供足够的自由就可以了

0
红薯官方
红薯官方

把Connection放到ThreadLocal这个楼上说得好。

然后造一个注解@Transaction吧

实现一个事务拦截器,自动开始事务和提交事务。

返回顶部
顶部