论坛首页 Java企业应用论坛

关于action+session bean+dao+jdbc

浏览 6734 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-10-13  
DAO
1.struts action+session bean+dao+jdbc或
  struts action+session bean+dao+hibernate
这种架构对于一个业务方法(比如就是一次转帐),我可以用session bean进行事务控制.现在假如我们不想用EJB这层(我们只用Tomcat),我想直接用一个简单java class来代替session bean,现在要进行事务控制,只能直接操作connection 或session了.我想在这种情况下是不是就要把DAO这层去掉了,否则我在简单java class中就不能直接操作connection 或session了嘛!
疑惑!请哪位前辈帮忙看一下l另外我们也不会Spring.其实我最主要想问的就是在这种情况下,是不是就不要DAO了.
   发表时间:2004-10-13  
可以用ThreadLocal来管理Connection和Transaction。搜索一下论坛,关于ThreadLocal的话题成吨。
0 请登录后投票
   发表时间:2004-10-13  
谢谢robbin的提醒,我搜索了相关主题看了一下,知道了可以用
ThreadLocal来管理Session和Transaction。Transaction的提交和Session的关闭在ServletFilter里面完成.
现在又有一个疑问就是:session.beginTransaction()是不是也应该在ServletFilter里面执行而不是在dao的对业务对象的CRUD方法里执行呢?
因为比如我有一个业务方法它要执行dao1.save()和dao2.update(),那我总不能在dao1.save()和dao2.update()中分别执行一个session.beginTransaction()吧!
0 请登录后投票
   发表时间:2004-10-14  
bluesky 写道
谢谢robbin的提醒,我搜索了相关主题看了一下,知道了可以用
ThreadLocal来管理Session和Transaction。Transaction的提交和Session的关闭在ServletFilter里面完成.
现在又有一个疑问就是:session.beginTransaction()是不是也应该在ServletFilter里面执行而不是在dao的对业务对象的CRUD方法里执行呢?
因为比如我有一个业务方法它要执行dao1.save()和dao2.update(),那我总不能在dao1.save()和dao2.update()中分别执行一个session.beginTransaction()吧!


这也是讨论过八十遍的问题了。自己去找找,或者看Spring JPetStore的做法。
0 请登录后投票
   发表时间:2004-10-14  
一个小建议,给网站做个目录索引之类的。斑竹能把精华帖子分门归类,初学者查找起来也很方便。另外现在论坛的search功能很弱的说
0 请登录后投票
   发表时间:2004-10-14  
谢谢各位前辈的提醒,小弟找到了想要知道的答案!

很谢谢Robbin大哥的以下示例:


java代码: 

1   /*
2    * Created on 2003-11-16
3    *
4    */
5   package com.javaeye.crm;
6   
7   import net.sf.hibernate.HibernateException;
8   import net.sf.hibernate.Session;
9   import net.sf.hibernate.SessionFactory;
10  import net.sf.hibernate.Transaction;
11  import net.sf.hibernate.cfg.Configuration;
12  import net.sf.hibernate.tool.hbm2ddl.SchemaExport;
13  
14  /**
15   *
16   * 获取Session连接工厂类
17   *
18   * @author Robbin Fan
19   *
20   */
21  public class HibernateSession {       
22         
23          private static final ThreadLocal sessionThread = new ThreadLocal();
24         
25          private static final ThreadLocal transactionThread = new ThreadLocal();
26         
27          private static SessionFactory sf = null;
28         
29          /**
30          * 获取当前线程使用的Session
31          *
32          * @return Session
33          * @throws HibernateException
34          */
35          public static Session currentSession() throws HibernateException {       
36                  Session s = (Session) sessionThread.get();               
37                  if (s == null) {
...}
38                          if (sf == null) sf = new Configuration().configure().buildSessionFactory();       
39                          s = sf.openSession();
40                          sessionThread.set(s);               
41                  }
42                  return s;
43          }
44  
45          /**
46          * 获取一个新的Session
47          *
48          * @return Session
49          * @throws HibernateException
50          */
51          public static Session newSession() throws HibernateException {       
52         
53                  if (sf == null) sf = new Configuration().configure().buildSessionFactory();       
54                  Session s = sf.openSession();
55                  return s;
56          }
57                 
58          /**
59          * 启动或者加入当前Session的Transaction
60          *
61          * @return Transaction
62          * @throws HibernateException
63          */
64          public static Transaction currentTransaction() throws HibernateException {
...}
65                  Transaction tx = (Transaction) transactionThread.get();
66                  if (tx == null) {
...}
67                          tx = currentSession().beginTransaction();
68                          transactionThread.set(tx);
69                  }
70                  return tx;
71          }
72         
73          /**
74          * 提交当前Session的Transaction
75          *
76          * @throws HibernateException
77          */
78          public static void commitTransaction() throws HibernateException {
...}
79                  Transaction tx = (Transaction) transactionThread.get();
80                  transactionThread.set(null);
81                  if (tx != null) tx.commit();
82          }
83  
84          /**
85          * 回滚当前事务
86          *
87          * @throws HibernateException
88          */
89          public static void rollbackTransaction() throws HibernateException {
...}
90                  Transaction tx = (Transaction) transactionThread.get();
91                  transactionThread.set(null);
92                  if (tx != null) tx.rollback();
93          }
94                 
95          /**
96          * 关闭当前线程使用的Session
97          *
98          * @throws HibernateException
99          */
100         public static void closeSession() throws HibernateException {                       
101                 Session s = (Session) sessionThread.get();               
102                 sessionThread.set(null);
103                 if (s != null) s.close();
104         }
105 
106         /**
107         * 根据映射文件和持久对象生成数据库DDL,生成文件为create_table.sql
108         *
109         * @param args 参数
110         */
111         public static void main(String[] args) {
...}
112                 try {
...}
113                         String conf = "hibernate.cfg.xml";
114                         if (args.length != 0) conf = args[0];
115                         Configuration cfg = new Configuration().configure("/" + conf);
116                         SchemaExport se = new SchemaExport(cfg);
117                         //se.setOutputFile("create_table.sql");
118                         se.create(true,true);
119                 } catch (HibernateException e) {                       
120                         System.out.println(e.getMessage());
121                 }
122                
123         }
124 }



在你的DAOImpl中,你直接:

java代码: 


2 Session session = HibernateSession.currentSession();
3 HibernateSession.currentTransaction();
4 .....
5 session.flush();
6


事务的提交和Session的close都在Filter里面完成,Filter里面代码如下:

java代码: 

1                  try {
...}
2                          HibernateSession.commitTransaction();
3                  } catch (HibernateException e) {               
4                          try {
...}
5                                  HibernateSession.rollbackTransaction();
6                          } catch (HibernateException e1) {
7                                  System.out.println(e1.getMessage());
8                          }       
9                          System.out.println(e.getMessage());
10                 } finally {
11                         try {
...}
12                                 HibernateSession.closeSession();
13                         } catch (HibernateException e) {
14                                 System.out.println(e.getMessage());
15                         }
16                 }




这是粗颗粒度的Transaction。

如果该DAO需要一个细颗粒度的事务的话,那么你就

java代码: 


2 Session session = HibernateSession.currentSession();
3 HibernateSession.currentTransaction();
4 .....
5 session.flush();
6 HibernateSession.commitTransaction();
7


这样就可以实现一个细颗粒度的事务,而且在该线程执行序列中,接下去的另一个方法调用也是类似:

java代码: 


2 Session session = HibernateSession.currentSession();
3 HibernateSession.currentTransaction();
4 .....
5 session.flush();
6


这样的代码,而HibernateSession.currentTransaction();会自己检查当前是否已经启动事务,如果发现没有启动事务,那么就会新启动一个事务的。

因此,如果你需要细颗粒度的事务的话,就在你方法里面 java代码: 

1 HibernateSession.commitTransaction();

如果你不需要细颗粒度事务的话,就不写这句代码就OK了,最后Filter会提交。
0 请登录后投票
   发表时间:2004-10-16  
什么叫粗颗粒事务和细颗粒事务啊?一直搞不懂?
0 请登录后投票
   发表时间:2004-10-16  
我是这样理解的,比如有一个DAO1,它有两个方法:update()和save(),如果你直接分别在这两个方法的内部开始了事务--完成了操作--提交事务,那么就是细粒度事务.但是你有可能有一个业务方法它需要分别调用DAO.update()和DAO.save(),那么你就可以在这个业务方法的开始 启动一个事务--DAO.update()--DAO.save()--提交事务,这时你就不要在DAO.update()和DAO.save()中控制事务了,这大概就是粗粒度吧(跨了两个方法).


说到这里我到也有了一个疑问,就象上述,假如我既需要上面的那个业务方法又需要
独立的DAO.update()和DAO.save(),换句话说就是我需要三个不同的事务,那么我肯定就不能在DAO.update()和DAO.save()中分别控制事务了.因为那样的话,我的业务方法就不能控制事务了.其实我想问的也就是是不是在一般情况下最好不要用细粒度事务,否则我有需求需要用粗度事务时,岂不是要修改DAO了.
0 请登录后投票
   发表时间:2004-10-16  
我是这样理解的,比如有一个DAO1,它有两个方法:update()和save(),如果你直接分别在这两个方法的内部开始了事务--完成了操作--提交事务,那么就是细粒度事务.但是你有可能有一个业务方法它需要分别调用DAO.update()和DAO.save(),那么你就可以在这个业务方法的开始 启动一个事务--DAO.update()--DAO.save()--提交事务,这时你就不要在DAO.update()和DAO.save()中控制事务了,这大概就是粗粒度吧(跨了两个方法).


说到这里我到也有了一个疑问,就象上述,假如我既需要上面的那个业务方法又需要
独立的DAO.update()和DAO.save(),换句话说就是我需要三个不同的事务,那么我肯定就不能在DAO.update()和DAO.save()中分别控制事务了.因为那样的话,我的业务方法就不能控制事务了.其实我想问的也就是是不是在一般情况下最好不要用细粒度事务,否则我有需求需要用粗度事务时,岂不是要修改DAO了.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics