jdbc一个connection 下的事务问题[转]

在不分层的情况下,一个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层;我们做分层应该是上层依赖下层的,下层依赖上层是不应该出现的。

猜你喜欢

转载自harveyzeng.iteye.com/blog/1559826
今日推荐