该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-07-09
JSF的确很方便,当界面上一次操作的数据量过大时,可以直接把实体Bean给Map过去。
如果需要校验的话可以使用Seam的特殊校验功能,或者可以找人单独做校验的程序,不过做这个很难受,一天8小时下来累得基本上不行了。 |
|
返回顶楼 | |
发表时间:2008-07-09
接触了一段时间的jsf 用netbeans做开发 发现jsf还挺不错 尤其netbeans自带的数据绑定 代码生成 并对jsf周期进行封装 使我们的业务逻辑非常清晰 事件机制 增加了交互性 但自带的那个jsf库是生成dojo代码 所以运行速度慢 但是你可以修改源代码 有自带的html现实 稍微修改一下就行了 当然netbeans对电脑配置要求高 当然netbeans也可以很多优化的 多了解点 就不会说jsf怎么 怎么不好了
|
|
返回顶楼 | |
发表时间:2008-07-09
引用 ADF有ajax功能,点击一个button时,我可以选择只刷新某个table或某个文本框或某个span等等。而且只需要改一个属性即可。
从这点就可以看出来,你真的没实际做过。也没有讨论的心要的。这样的贴子也没什么必要回了 大家都是在空口说白话 怎么说都行。 |
|
返回顶楼 | |
发表时间:2008-07-09
nihongye 写道 引用 对于openSessionInView的问题应该是一直存在的,不是早期spring的问题,就像seam文档中所说,当使用openSessionInView模式,事务的提交必须等到渲染的完成,如果业务恰恰是在事务提交时出现了异常,那么客户端又怎么能知道呢?
也许是我孤陋寡闻不知道spring是怎么重新实现了这一模式,敬请答案! 不知道你是否理解错了seam说的,事务的提交必须等到渲染的完成这点是完全不成立的,事务可以手工,一般使用让spring的transactionmanager加上aop进行处理。 openSessionInView模式正是如你下面说的在事务完结后,仍"保持实体的托管状态"。 早期的spring存在的问题是在hibernate事务管理器中:“在事务抛出异常后,它没清空托管的实体,从而导致view的渲染出现脏数据”。 引用 conversation在设计上对于长会话状态会放置在session中,同时又能杜绝httpSession少有的并发问题,你说的脏数据问题我理解是不存在的。而且converstaion的长会话面向的是一次长业务处理,但不会对常驻会话的数据负责,所以conversation降为临时会话时,就会清理所有长会话数据,那么就和httpSession的职责进行更明确的划分!
我所说的脏数据的意思是“长业务处理,同时考虑业务处理人员的并发操作,从而converstaion不能及时的反映出当前的数据状态,seam在事务异常时自动清空托管实体(突然想起,在jpa规范的3.3.4 Transaction Rollback做了明确的规定)?” 看看seam文档里的这段话: EJB session beans feature declarative transaction management. The EJB container is able to start a transaction transparently when the bean is invoked, and end it when the invocation ends. If we write a session bean method that acts as a JSF action listener, we can do all the work associated with that action in one transaction, and be sure that it is committed or rolled back when we finish processing the action. This is a great feature, and all that is needed by some Seam applications. However, there is a problem with this approach. A Seam application may not perform all data access for a request from a single method call to a session bean. * The request might require processing by several loosly-coupled components, each of which is called independently from the web layer. It is common to see several or even many calls per request from the web layer to EJB components in Seam. * Rendering of the view might require lazy fetching of associations. The more transactions per request, the more likely we are to encounter atomicity and isolation problems when our application is processing many concurrent requests. Certainly, all write operations should occur in the same transaction! Hibernate users developed the "open session in view" pattern to work around this problem. In the Hibernate community, "open session in view" was historically even more important because frameworks like Spring use transaction-scoped persistence contexts. So rendering the view would cause LazyInitializationExceptions when unfetched associations were accessed. This pattern is usually implemented as a single transaction which spans the entire request. There are several problems with this implementation, the most serious being that we can never be sure that a transaction is successful until we commit it—but by the time the "open session in view" transaction is committed, the view is fully rendered, and the rendered response may already have been flushed to the client. How can we notify the user that their transaction was unsuccessful? Seam solves both the transaction isolation problem and the association fetching problem, while working around the problems with "open session in view". The solution comes in two parts: * use an extended persistence context that is scoped to the conversation, instead of to the transaction * use two transactions per request; the first spans the beginning of the restore view phase (some transaction managers begin the transaction later at the beginning of the apply request vaues phase) until the end of the invoke application phase; the second spans the render response phase spring的 persistence-context 一定是 transaction-scope的吗? 事务结束,session也关闭? 如果是这样,那OpenSessionInView确实可能出现页面渲染结束,但是事务没有提交成功,错语信息无法传达给用户的问题。如果OpenSessionInView,但是事务提交后,并不关闭session, 如果事务提交失败,会导致session的缓存里有脏数据吗? 就算不用conversation,在高并发的时候,一样有可能出现读脏数据的,除非对数据库做悲观锁,不然都有可能在你提交数据之前,别人已经改动过数据。关键是有多大的并发量,出现这种情况的机率有多大,以及出这种情况后会不会导致数据库出现不完整数据。在发生机率不是很高的情况下,用乐观锁,我觉得就够用了。 Conversation主要的好处是,扩大了session的生命期,减少发生LazyInitializationException,同时Conversation可以当作是一个很好缓存,把业务处理过程的中间数据放在其中,最后一把提交。我们的项目里就有这样一个场景,用户需要创建一份建议书,而建议书里包含很多合同的草稿,有些合同草稿是必要的,有些是不必要,有些是数目定死的,有些是任意数目的,我们用一个页面流程来让用户完成对这份建议书的创建,但是直到用户最终决定要保存的时候,才能把这份建议书放到数据库中,因为不能存在不完整的建议书,不能存在没有建议书的合同草稿。这个场景下,用conversation就相当的方便的,在用户最终提交前,数据都是放到conversation中的,用户在最后提交的时候,我们再通一个transaction把数据放到数据库中。更可贵的是,由于conversation可以并发,一个用户可以同时编辑数份建议书,而不相冲突,虽然我们项目中还没有给用户提供这样功能,但是conversation确实有这样的能力,这也是seam引以为荣的工作区概念。如果没有conversation,都塞到session中,将会相当的麻烦,因为那样的话,我们还得要控制对SESSION的并发访问,控制何时清理这些数据。而Conversation帮我们完成并发控制,并在conversation终止时自动清理数据,而且conversation往往两三分钟就超时了,要比session要容易清理得多,因为session往往超时时间很长的。 |
|
返回顶楼 | |
发表时间:2008-07-09
xiao0556 写道 引用 ADF有ajax功能,点击一个button时,我可以选择只刷新某个table或某个文本框或某个span等等。而且只需要改一个属性即可。
从这点就可以看出来,你真的没实际做过。也没有讨论的心要的。这样的贴子也没什么必要回了 大家都是在空口说白话 怎么说都行。 你在空口说白话,我没有。 另外,你觉得JSF跟ajax有什么可比较的么?你知道什么是JSF,什么是ajax么? |
|
返回顶楼 | |
发表时间:2008-07-09
引用 This pattern is usually implemented as a single transaction which spans the entire request.
usually,写这段文字的人分明没真正使用过spring,使用spring的多数是搞一个Service类,然后Service类的方法作为事务的边界。一样的,即使一个request,多个事务也是一样ok的。事务完成后,session以never flush的形式保持到view渲染完成后关闭。 引用 spring的 persistence-context 一定是 transaction-scope的吗? 事务结束,session也关闭?
transaction scope,extended-scope是在jpa才有的概念,hibernate里根本没有。 在没有open session的时候,spring的管理的session可以理解为transaction-scope的。但有了外部open session了,则不是。 引用 但是事务提交后,并不关闭session, 如果事务提交失败,会导致session的缓存里有脏数据吗?
清除托管对象,并不需要关闭session,session.clear就ok了。改动的对象为托管对象,事务失败后,后续的查询见到的对象还是这个托管对象,所以事务失败后,清除托管对象这点是很正确的。 |
|
返回顶楼 | |
发表时间:2008-07-09
qingyujingyu427 写道 xiao0556 写道 引用 ADF有ajax功能,点击一个button时,我可以选择只刷新某个table或某个文本框或某个span等等。而且只需要改一个属性即可。
从这点就可以看出来,你真的没实际做过。也没有讨论的心要的。这样的贴子也没什么必要回了 大家都是在空口说白话 怎么说都行。 你在空口说白话,我没有。 另外,你觉得JSF跟ajax有什么可比较的么?你知道什么是JSF,什么是ajax么? 本来不想回这个贴了,不过你这样说我有点不开心 我做JSF这么长时间了怎么就不知道JSF是什么了? 我不想搞人身攻击 也不希望别人攻击我 只用实际的例子和代码说话。上面的例子 你修改数据的时候 无非是弹出窗口和 跳转页面。那我想问一下 你弹出窗口修改完数据后 怎么刷新父窗口? 你跳转就跳出protel了 就算跳不出去,你跳回来查询条件没了,第几页也没了 怎么办?你可以把状态存起来 可是跳转的时候一但出去protel环境就不是一个session了。问题是可以解决但不是你说的那么简单?你说的例子 只能是当例子 真正的开发是不会那样简单的。我们的环境是在protel+seam里,对话环境是seam提的一个重要功能 但在protel里基本不能用 后来自己打补丁 可以用了但是也不是很稳定 保险的作法是每次都传cid 多么麻烦 真正用起seam来如果你应用交互要求不高 还是可以的 但是一但对复杂交互要求高了 有一大堆的坑等着你。关于我说的例子 我们是封装了一个弹出窗口的JSF组件解决的 可以刷新窗口的区域 可以开启对话环境。 |
|
返回顶楼 | |
发表时间:2008-07-09
nihongye 写道 引用 This pattern is usually implemented as a single transaction which spans the entire request.
usually,写这段文字的人分明没真正使用过spring,使用spring的多数是搞一个Service类,然后Service类的方法作为事务的边界。一样的,即使一个request,多个事务也是一样ok的。事务完成后,session以never flush的形式保持到view渲染完成后关闭。 引用 spring的 persistence-context 一定是 transaction-scope的吗? 事务结束,session也关闭?
transaction scope,extended-scope是在jpa才有的概念,hibernate里根本没有。 在没有open session的时候,spring的管理的session可以理解为transaction-scope的。但有了外部open session了,则不是。 引用 但是事务提交后,并不关闭session, 如果事务提交失败,会导致session的缓存里有脏数据吗?
清除托管对象,并不需要关闭session,session.clear就ok了。改动的对象为托管对象,事务失败后,后续的查询见到的对象还是这个托管对象,所以事务失败后,清除托管对象这点是很正确的。 谢谢nihongye MM的指点。看来在处理单次request的时候,spring经过配置后确实能够完成和seam同样的功能。也就是,在处理request之前开始session,在执行spring bean里的的业务方法的前后开启和提交事务,在完成页面渲染后关闭session。 但是很可惜,在用jsf的时候,处理业务逻辑,处理结果页面的渲染,是在后一个request里完成的。POST的时候调用业务方法,处理完后发送一个redirect,让客户端跳转到处理结果页面,客户端收到302后,用GET请求指定页面,这时服务端才渲染上一次处理的结果呢。在这种情况下,spring opensessioninview如何处理呢?这种情况下如果不能让hibernate session 跨越这次跳越,而是在下一次GET的时候又开始新的session,那么不是得做一大堆的重新从数据库里刷新托管对象的操作? 我觉得在与hibernate配合这一方面,seam确实做得比spring要好。不是说spring做不到,而是seam在这方面更易用。 |
|
返回顶楼 | |
发表时间:2008-07-09
To xiao0556:
1. 我开始从来没提过ajax,而你好像对我的观点持相反意见,然后用ajax来反驳我的观点。 2. 我不认为JSF和ajax是一个级别的东西,他们有什么可比较之处。既然你有许多的JSF经验,难道你认为你说的ajax的那段话很有道理么? 3. 帖900多行代码到帖子里大家看着都不舒服。不太清楚贴这些代码有什么意义。证明你用过JSF? 4. 关于弹出窗口的问题。在adf里弹出窗口关闭时,可以刷新整个父窗口,也可以选择性的刷新某个或几个区域。我一开始已经说了我对seam不熟,所以用adf举例。看你的描述,或许seam的JSF实现不够好或者你们用的有问题? 5. JSF只是一个标准。每个厂商的实现都不一样,可能有的好,有的坏。如果我开发了一套实现,你觉得很烂,但并不能说明JSF不好。像以前大家批判JSF都是集中在批判状态存在服务器端的问题,我认为这样辩论是可以的。而你说了个这么细节的问题,而我也没看出来你是想用这个问题到底来证明JSF的哪个特点不好。 |
|
返回顶楼 | |
发表时间:2008-07-09
Anatorian 写道 谢谢nihongye MM的指点。 客气啊,我男的。 http://www.hibernate.org/43.html 中的Can I commit the transaction before rendering the view?说的问题,值得spring借鉴 |
|
返回顶楼 | |