实例详解 EJB 中的六大事务传播属性
?
图 1 显示两个方法均执正常行完毕,没有任何异常抛出。
图 2. 实体 Bean Person 对应的数据库表
?
CreatePerson() 方法正常执行完毕后,ID 为 200 的人被持久化到数据库中。
图 3. 实体 Bean Address 对应的数据库表
?
CreateAddress() 方法正常执行完毕后,ID 为 100 的地址被持久化到数据库中。
这就说明这两个方法均在事务的环境中进行了持久化的操作,且没有回滚。
下面我们使用依赖注入,将 SessionContext 注入到 ClientEJB,并在 createPerson() 中调用 setRollbackOnly() 将这个方法所在的事务设置成 Doomed 事务。Doomed 事务就是那些铁定要回滚的事务,无论他进行了什么操作,无论成功与否,都要回滚,这就是他的宿命。
清单 9. 客户端 createPerson() 回滚
CreatePerson() 方法正常执行完毕后,ID 为 88 的人被持久化到数据库中。
图 5 .Address 表
?
CreateAddress() 方法正常执行完毕后,ID 为 55 的地址被持久化到数据库中。
下面我们将 ClientEJB 设置为 Doomed 事务,而保持 CommonEJB 不变,看看是什么情况。
外围事务回滚,不影响新开启的事务。
清单 13. Requires_New 属性中被设定为 Doomed 的 ClientEJB
这就因为 createPerson() 所在的事务进行了回滚,而 createAddress() 所在的事务没有回滚。
内围事务回滚,不影响外围事务。
下面我们将 CommonEJB 设置为 Doomed 事务,而保持 ClientEJB 不变,看看是什么情况。
清单 14.Requires_New 属性中被设定为 Doomed 的 CommonEJB
以上两种情况说明,Require_New 开启的是一个新事务,外围事务也就是调用者或客户端所在事务的回滚,不会影响到这个新开起的事务;同样,新开起的事务的回滚与否对外围事务也没有任何影响。
?
图 9.Address 表
?
当调用者自己新开起一个事务,或已经处于某个事务之中的时候,被调用者会加入调用者的事务。这样调用者和被调用者就处于同一个事务之中,在任何一个方法内出现引起事务回滚的事件,调用者和被调用者都要回滚。
当调用者不在事务中运行,而被调用者的事务传播属性为“SUPPORTS”时,被调用者也不会开启新事务,仍旧在无事务的环境中运行,这个时候和普通得 Java 方法之间的调用毫无区别,任何一个 Java 程序员对这种情况都会司空见惯,这里也不再赘叙。
?
如下所示,我们将 createPerson() 方法新开起的事务设定成 Doomed 事务,执行完毕后,由于事务的回滚,Person 数据并没有持久化到数据库中。而 createAddress() 方法一直在无事务的环境中运行,所以当外围事务回滚的时候,对他并没有人很影响。
清单 19.Not_Supported 属性中 ClientEJB 客户端
图 12.Address 表
?如清单 22 我们把 ClientEJB 的传播属性修改为”Mandatory”,因为 Main() 不在事务中运行,所以在 Main() 方法中调用 ClientEJB 是就会抛出异常。
例如:
清单 22.Mandatory 属性中 ClientEJB
?
综上所述,EJB 中事务的传播属性可以用如下表格进行概括:
表 1. 事务传播属性总表
王汉敏拥有 Sun 公司的 Sun Certified Java Programmer, Sun Certified Web Component Developer Sun Certified Developer for Java Web Services Sun Certified Business Component Developer 认证 , 一直致力于 J2EE 领域软件的开发。