一、事务的基本知识
1、什么是事务?
通常,我们把一组连续不可分的数据库操作称为一个事务。
事务解决了两大问题,原子操作,数据共享
原子操作,是由不可分操作组成的,使这些不可分的操作,一同操作成功或者一同失败。
2、事务的ACID特性
A(Atomicity)原子性:操作不可分割,一连串操作当作一个整体执行;
C(Consistency)一致性:数据库的数据在事务完成前后保持一致;
I(insulation)隔离性:多个事务独立地执行,一个事务的执行不影响另一个事务的执行结果,隔离性即一个事务对另一个事务的可见性;
D(durability)持久性:事务操作的结果应该保留下来。
3、事务的类型
(1) 扁平式事务:事务要么成功,要么失败,不允许包含子事务;
(2) 嵌套式事务:一个大事务里潜逃多个小事务,允许子事务回滚。各个子事务必须都成功,整个事务才能成功提交;
Tips:EJB不支持嵌套式事务。
4、分布式事务(Distributed Transaction)
(1) 什么是分布式事务?
跨越多个数据资源的事务叫做分布式事务。
数据资源:对数据进行存储、管理的空间(如Database,JMS中的主题队列,File System,后端系统等)。
JDBC只支持本地事务。
本地事务:只负责处理单个数据资源(Data Resource)的事务。
(2) 为什么要使用分布式事务?
企业级应用中,业务需要跨越多个数据资源,并且要作为一个整体来执行,就需要使用分布式事务。
(3) 分布式事务的原理
两阶段提交协议(Two-phrase commit protocol)
① 四个角色:A、Data Resource(数据存取的目的地,通常为Database)
B、Resource Manager(负责数据资源管理,通常为Database device)
C、Transaction Manager(负责对资源管理器施加事务的管理)
D、Transaction Coordinator(事务协调器,负责对多个事务管理器进行协调,保证分布式事务能够执行)
②Two-phrase commit protocol执行过程(类似于投票机制中的一票否决制)
第一阶段:事务准备阶段
a、事务协调器(Transaction Coordinator)向各个事务管理器(Transaction Manager)发送事务准备提交的信息;
b、Transaction Manager向Transaction Coordinator回应是否提交事务;
c、Transaction Coordinator记录日志(各个Transaction Manager的回应);
第二阶段:事务提交阶段
d、Transaction Coordinator向各个Transaction Manager发送事务提交信息;
e、Transaction Manager将执行结果返回给Transaction Coordinator。
二、EJB中的事务机制
1、JTS(Java Transaction Service)
JTS协议基于OTS协议,JTS协议即Java中分布式事务服务的协议。
JTA(Java Transaction API):
① UserTransaction(EJB或其他组件用该接口使用分布式事务)
② TrasactionManager:应用服务器与分布式事务服务器的接口
③ ResourceManager
EJB事务调用流程:EJB→UserTransaction→JTA→JTS→OTS
2、EJB的事务
① EJB事务的特点
提供声明式事务与编程式事务
声明式事务:应用程序只需要关心业务逻辑,由容器来负责事务的管理。
编程时事务:应用程序编码人员自己写事务代码。
② EJB事务编程的类型
A、CMT 容器管理事务
B、BMT Bean管理事务
C、Client-MT Client-Controlled Transaction客户端管理事务
实体Bean只能用CMT。
CMT:
由容器实现的远程对象/拦截器,负责调用中间件服务。
优点:在应用程序代码中,不用编写事务服务代码;
缺点:粗粒度,只能在方法级别控制事务。
EJB Bean类中编程方式来使用事务(BMT):
优点:细粒度地控制事务
缺点:事务代理与业务代码纠缠
Client-controlled Transaction:
优点:客户端可以精确控制事务
缺点:可能会因为网络问题引起是事务的回滚。
3、EJB事务边界的划分
事务边界:事务边界是指事务从哪里开始。
CMT的事务特性:
Required:Bean类的方法必须要在事务环境下运行,这是容器默认的事务机制。
事务特性只能使用在CMT。
RequiredNew:Bean类中的方法必须在一个新的事务环境下运行。
Supports:Bean类的方法不需要支持事务。如果客户端有事务,则继续沿用原事务环境。
Mandatory:Bean类中方法必须要在事务环境下运行。客户端不启动事务则报错。
NoSupported:Bean类中方法不支持事务。如果客户端启动了事务,则挂起该事务。
Never:Bean类中的方法不支持事务。如果客户端启动了事务,则报错。
三、EJB事务的编程
1、CMT
@TransationManagement 用在类前,标注该EJB事务管理方式为Bean | Container(默认)
@TrasactionAttribute 用在方法前,标注事务特性(事务的边界)
@SessionContext.setRollbackOnly() 回滚标识,setRollbackOnly()方法必须在事务环境下运行。
EJB容器对于非受查异常(主要指RuntimeException)会回滚,事务对于受查异常则会提交事务。
2、BMT
UserTransaction:
① interface
② 提供控制事务的方法
③ 由容器实现,可以使用@Resource注入
UserTransaction.begin()| commit()| .rollback()
3、客户端控制事务
调用EJB的方法,要求EJB必须采用CMT形式。
4、事务的隔离性
事务的隔离级别:
A、Read uncommitted:性能最高
B、Read committed:解决脏读问题
C、Repeatable read:解决重复读取问题
D、Serializable:解决幻读问题
EJB本身不提供隔离级别的设置,可以通过直接设置数据库(连接池)的隔离级别。
SessionSynchronization接口:
在有状态会话Bean中,如果事务失败,可以恢复其状态。
afterbegin():在事务刚启动是,容器调用该方法,一般做状态初始值的保存。
beforeCompletion():在事务完成之前,容器回调。
afterCompletion():在事务提交之后调用,boolean值由容器提供。true表示事务提交成功,false则表示事务失败。在此方法中,做状态的恢复。