浏览 6734 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2004-10-13
struts action+session bean+dao+hibernate 这种架构对于一个业务方法(比如就是一次转帐),我可以用session bean进行事务控制.现在假如我们不想用EJB这层(我们只用Tomcat),我想直接用一个简单java class来代替session bean,现在要进行事务控制,只能直接操作connection 或session了.我想在这种情况下是不是就要把DAO这层去掉了,否则我在简单java class中就不能直接操作connection 或session了嘛! 疑惑!请哪位前辈帮忙看一下l另外我们也不会Spring.其实我最主要想问的就是在这种情况下,是不是就不要DAO了. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2004-10-13
可以用ThreadLocal来管理Connection和Transaction。搜索一下论坛,关于ThreadLocal的话题成吨。
|
|
返回顶楼 | |
发表时间: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()吧! |
|
返回顶楼 | |
发表时间: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的做法。 |
|
返回顶楼 | |
发表时间:2004-10-14
一个小建议,给网站做个目录索引之类的。斑竹能把精华帖子分门归类,初学者查找起来也很方便。另外现在论坛的search功能很弱的说
|
|
返回顶楼 | |
发表时间: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代码: 1 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代码: 1 2 Session session = HibernateSession.currentSession(); 3 HibernateSession.currentTransaction(); 4 ..... 5 session.flush(); 6 HibernateSession.commitTransaction(); 7 这样就可以实现一个细颗粒度的事务,而且在该线程执行序列中,接下去的另一个方法调用也是类似: java代码: 1 2 Session session = HibernateSession.currentSession(); 3 HibernateSession.currentTransaction(); 4 ..... 5 session.flush(); 6 这样的代码,而HibernateSession.currentTransaction();会自己检查当前是否已经启动事务,如果发现没有启动事务,那么就会新启动一个事务的。 因此,如果你需要细颗粒度的事务的话,就在你方法里面 java代码: 1 HibernateSession.commitTransaction(); 如果你不需要细颗粒度事务的话,就不写这句代码就OK了,最后Filter会提交。 |
|
返回顶楼 | |
发表时间:2004-10-16
什么叫粗颗粒事务和细颗粒事务啊?一直搞不懂?
|
|
返回顶楼 | |
发表时间: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了. |
|
返回顶楼 | |
发表时间: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了. |
|
返回顶楼 | |