关于事务的满脑袋酱子,解惑:本地、JTA、CMT

传统上J2EE有两种事务管理策略:全局或者本地事务
全局的由app server保证,如JTA。而本地则是针对某种资源的,如JDBC连接的事务。
其中,全局事务是为了保证多种事务资源的共同工作。但是如果是用本地的事务,则容器(app server)无法保证跨资源的事务。
JTA是一种全局的事务。但是JTA是笨重的,且JTA的事务一般需要通过JNDI获得,所以JNDI和JTA一般联用。而且JTA代码一般不能跨App server,会受限于某种特定的容器。
所以更好的方式是使用EJB CMT(Container Managed Transaction),它的特点是使用声明性事务,而不是编码事务管理。
所以,虽然EJB天然结合了JNDI,但是并不受限于容器(声明性)。
但是CMT又依赖于JTA和App server环境(或者说支持EJB的App server,Tomcat这些Servlet容器就不行啦)。所以这种事务如果依赖于EJB或者EJB的装饰封装则要花不少资本投资App server(不是钱也至少要人,如JBoss)。
但是,我们还有更好的选择,如Spring,或者很多Aop实现,EJB3等等。
而本地的事务策略虽然实现容易,但是缺点显著。它不能在多资源间实现事务支持,并且这种事务对变成模型的侵入也很大(传统JDBC事务使用起来就是这样)。而且如JDBC连接也不能与其他JTA事务协同被管理。如你的JDBC和某个其它事务绑定(如两个JDBC Connection)起来,如果遇到一个失败你如何将两个rollback?(这个是我自己演绎的)
下面是广告:
Spring解决了这个问题。它提供了一个持续的模型,可以应用在大多数环境。也就是说你可以灵活的更换它支持的各种事务策略(你也可以自己扩展)。而且Spring两种方式的事务都支持(声明/编码),当然Spring推荐使用声明的(侵入小,灵活)。

MB,本来写了不少体会,结果倒霉没有保存,如果有时间我再考虑一下是否重写吧,损失惨重!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.