被调用方法的事物属性1、 事务的涵义和要求
事务是必需作为一个单元执行的一组操作——比如银行转账中一方账户里扣除金额同时在另一方账户中添加相应金额的两个操作,是要求作为一组操作来进行的(此类操作要求是同步的;EJB事务中的一组操作可以是同步的,也可以是异步的)。事务中的所有操作是在一个短周期内顺序或并行执行的。 2、 事务的属性——ACID Atomicity(原子性):是指事务中所有操作是作为一个整体来完成的性质;它要求在事务结束时,所有操作全部完成(事务成功),或都没有完成(事务失败)。 Consisitency(一致性):是指数据保持完整;它要求在事务结束时,数据的逻辑规则得以保持; Isolation(隔离性):要求事务的处理过程和中间状态对于外部环境应该是透明的 Durability(耐久性):要求事务提交时,其造成的改动对其它程序不透明。 3、 分布式事务和JTA 分布式事务是说这样的一种事务:它的所有操作使用不同进程或计算机上的资源,因此它要求在涉及的资源间进行专门的协调——JTA就是这样一个事务管理器:它定义了一组接口,省略了显式编写两阶段提交协议(一种策略,通过“准备”和“提交”两条命令来协调所有资源管理器的动作,以减少分布式操作中出现的冲突或错误)的环节,从而方便了客户、企业Bean或资源管理器参与到容错性分布式事务中。 4、 声明性的事务管理VS显式划分的事务管理 显式划分的事务管理: 需要用到一些相当复杂的API,还需要在业务逻辑中编写事务性代码。 声明性的事务管理: EJB服务器可以根据部署其间定义的事物属性隐式地对事物进行管理,通过@java.ejb.!TrasactionAttribute注解或EJB部署描述文件,为整个EJB或其中的方法设置以下事务属性: NotSupported Supports Required(默认事物属性) RequiresNew Mandatory Never 从而只需修改注解或XML,就可以对EJB事务行为进行控制。 下面分别介绍这两种方法的使用: 1) 使用@!TrasactionAtrribute注解 !TrasactionAttribute是一种枚举类型,包括:MANDATORY, REQUIRED, REQUIRES_NEW, SUPPORTS,NOT_SUPPORTED, NEVER这几个值,可以应用于bean class,也可以单独应用于其中的每个方法。使用的方法是,在类或方法前注解: @TransactionAttribute(NOT_SUPPORTED) 如果在一个已经注解了事物属性的bean类的方法上再注解不同的事物属性,那么该方法的事物属性可覆盖之前的bean类事物属性。 2) 在XML中设置事物属性 在XML部署描述文件中,可以用<container-transaction>元素指定EJB的事物属性。 5、 事务范围 事务范围是指涉及某个事务的所有EJB,它可以根据方法执行的线索来界定:在事务执行时,当EJB某个方法被调用,事务就会被传播到该EJB中,而该EJB也会被相应包含在事务范围内。
1.EJB事务分类
- 容器管理事务的回滚
你能够在任何企业Bean中使用容器管理事务:会话Bean、实体Bean或者 Message-driven Bean。容器管理事务可以分两种:
第一,如果产生一个系统异常,容器将自动回滚该事务。
第二,通过调用EJBContext接口SetRollbackOnly方法,Bean方法通知容器回滚该事务。如果Bean抛出一个应用异常,事务将不会自动回滚,但可以调用SetRollbackOnly回滚。
- bean管理事务
在一个Bean管理事务中,会话Bean或者Message-driven Bean是用代码显式设置事务界线的。实体Bean不能使用Bean管理事务,只能使用容器管理的事务。虽然容器管理事务Bean需要较少的代码,但它也有一个局限:方法执行时,它只能关联一个事务或不关联任何事务。如果这个局限使你Bean编码困难,你应该考虑使用Bean管理事务
其中bean管理事务可以分为JDBC事务
JDBC 事务
JDBC事务通过DBMS事务管理器来控制。你可能会为了使用会话Bean中的原有代码而采用JDBC事务将这些代码封装到一个事务中。使用JDBC事务,要调用java.sql.Connection接口的commit和rollback方法。事务启动是隐式的。一个事务的从最近的提交、回滚或连接操作后的第一个SQL的语句开始。(这个规则通常是正确的,但可能DBMS厂商的不同而不同)
JTA 事务
JTA是Java Transaction API 的缩写。这些API 允许你用独立于具体的事务管理器实现的方法确定事务界限。J2EE SDK 事务管理器通过Java事务服务(Java Transaction Service, JTS)实现。但是你的代码并不直接调用JTS中的方法,而是调用JTA方法来替代,JTA方法会调用底层的JTS实现。
JTA事务被J2EE 事务管理器管理。你可能需要使用一个JTA事务,因为它能够统一操作不同厂商的数据库。一个特定DBMS的事务管理器不能工作在不同种类的数据库上。然而J2EE事务管理器仍然有一个限制——它不支持嵌套事务。就是说,它不能在前一个事务结束前启动另一个事务。
要自己确定事务界限,可以调用javax.transaction.UserTransaction接口的begin、commit和rollback方法来确定事务界限(该接口只能在SessionBean中使用,实体Bean不允许使用用户自定义的)。
2.事务属性
Required
如果客户端正在一个运行的事务中调用一个企业Bean的方法,这个方法就在这个客户端的事务中执行。如果客户端不关联一个事务,这个容器在运行该方法前开始一个新的事务。Required属性在许多事务环境中可以很好的工作,因此你可以把它作为一个默认值,至少可以在早期开发中使用。因为事务的属性是在部署描述符中声明的,在以后的任何时候修改它们都很容易。
RequiresNew
如果客户端在一个运行的事务中调用企业Bean的方法,容器的步骤是:1.挂起客户端的事务
2.开始一个新的事务
3.代理方法的调用
4.方法完成后重新开始客户端的事务
如果客户端不关联一个事务,容器运行这个方法以前同样开始一个新的事务。如果你想保证该方法在任何时候都在一个新事物中运行,使用RequiresNew属性。
Mandatory
如果客户端在一个运行的事务中调用企业Bean的方法,这个方法就在客户端的事务中执行。如果客户端不关联事务,容器就抛出TransactionRequiredException 异常。如果企业Bean的方法必须使用客户端的事务,那么就使用Mandatory属性。
NotSupported
如果客户端在一个运行的事务中调用企业Bean的方法,这个容器在调用该方法以前挂起客户端事务。方法执行完后,容器重新开始客户端的事务。如果客户端不关联事务,容器在方法运行以前不会开始一个新的事务。为不需要事务的方法使用NotSupported属性。因为事务包括整个过程,这个属性可以提高性能。
Supports
如果客户端在一个运行的事务中调用企业Bean的方法,这个方法在客户端的事务中执行,如果这个客户端不关联一个事务,容器运行该方法前也不会开始一个新的事务。因为该属性使方法的事务行为不确定,你应该谨慎使用Supports属性。
Never
如果客户端在一个运行的事务中调用企业Bean的方法,容器将抛出RemoteException异常。如果这个客户端不关联一个事务,容器运行该方法以前不会开始一个新的事务。
定义事务属性的意义: 事务最大的特征在于其传播性,事务是靠传播来完成其工作单元的定义的,因此某个EJB或某个类是否会被传播到决定了它是否会被包含在整个事务的内,从而决定了事务管理器是否会对它进行托管。而事务属性就是定义了一个EJB或类被传播的特性