在java事务管理中,三种可用的模型分别为本地事务模型,编程式事务模型以及声明式事务模型。
ACID是事务中所持有的属性名缩写,这些属性为:原子性(Atomicity),一致性(Consistency),隔离性(Isolation),持久性(Durability)。
1.本地事务模型
指事务管理是被底层的数据库系统或JMS消息提供者来处理的。
问题:本地事务模型在使用XA全局事务协调多个资源的时候,是不能同时并发存在的。
2.编程式事务模型
与本地事务模型最大的区别在于前者管理的是事务,而不是连接。
只应在必要的情况下才使用,例如:客户端初始事务,局部化JTA事务,长时间运行的事务(一个事务跨多个服务器请求)。
3.声明式事务模型
在使用编程式事务模型时,开发者必须显式地使用begin(),commit()和rollback()方法来开始,提交和回滚一个事务,而对于声明式事务模型而言,容器对事务进行管理。
注意:在EJB中,ejbContext.setRollbackOnly()被业务逻辑方法调用时使用的是Supports,NotSupports或Never事务属性,容器必须抛出一个java.lang.IllegalStateException,throw new EJBException()效果等于ejbContext.setRollbackOnly()。
事务属性
事务隔离级别:
1)TransactionReadUncommitted:这个设置是隔离级别中的最低值,该隔离级别允许事务读取到其他事务未提交到数据库中的数据。
2)TransactionReadCommitted:该隔离级别允许在多个事务访问相同的数据时,隐藏其他事务未提交的数据(大部分数据库默认隔离级别)。
3)TransactionRepeatableRead:该级别保证在事务中所读取到的数据集都是相同的(可重复读)。
4)TransactionSerializable:隔离级别中最高的设置,某一个时刻只有唯一一个事务被允许执行。
- Serializable(串行化):一个事务在执行过程中完全看不到其他事务对数据库所做的更新。
- Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他事务对已有记录的更新。
- Read Commited(读已提交数据):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且能看到其他事务已经提交的对已有记录的更新
- Read Uncomitted(读未提交数据):一个事务在执行过程中可以拷打其他事务没有提交的新插入的记录,而且能看到其他事务没有提交的对已有记录的更新。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以有优先考虑把数据库系统的隔离级别设为Read Commited,它能够避免脏读,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
A.悲观锁:指在应用程序中显示的为数据资源加锁。尽管能防止丢失更新和不可重复读这类并发问题,但是它会影响并发性能,因此应该谨慎地使用。例如:select for update 。本次事务提交之前(事务提交时会释放事务过程中的锁) ,外界无法修改这些记录。
B.乐观锁:乐观锁假定当前事务操作数据资源时,不回有其他事务同时访问该数据资源,因此完全依靠数据库的隔离级别来自动管理锁的工作。应用程序采用版本控制手段来避免可能出现的并发问题。
4.XA事务处理
XA接口是系统级别的双向接口,该接口是单个事务管理器与一个或多个资源管理器之间的沟通桥梁。
事务管理器控制着JTA事务。
资源管理器负责控制和管理实际的资源(数据库或JMS队列)。
XA接口应该只被用于你想要在相同事务环境内协调多个资源(DB或JMS)
4.1在JMS中使用XA
在XA环境下一个资源必须实现javax.transaction.xa.XAResource接口才能被包含进XA全局事务。对于JMS而言,这是通过在具体的应用程序服务器中使用管理控制台或者配置文件的方式来说明,而你开启XA功能的配置文件的方式来说明的。
4.2在数据库中使用XA
在数据库中启用XA是通过使用相应的数据库驱动来实现的。