首页 > 代码库 > EJB Container Manage Transaction
EJB Container Manage Transaction
你脑海中事务的概念是什么?
先用最直白的话解释解释:对数据库操作我们最熟悉的是写SQL语句数据数据库建库、建表、操作表等,我们可以理解事务是一个规范只要操作数据库时按着这个规范做即可满足要求,可以把一条SQL语句加入到这个规范中也可以把很多语句加入规范中,只要加入到这个规范中的语句就会遵循这个规范的原则。
对于数据库不应该仅仅理解为写一条SQL语句是对数据库的操作,对数据库的所有操作都是在事务中进行的,即使仅仅一条插入语句也会开启关闭事务在事务中进行,因此可以把事务看作是操作数据库的最小单元,对数据库的其它一些特性的考虑也需要以事务为单位。
正规点的定义是:事务是访问数据库的一个操作序列,数据库系统通过事务集来完成数据库的存取,事务正确的结果是是数据库从一种状态变为另一种状态。
事务既然是一种规则那么它有自己的原则,主要有四个原则ACID。
原子性
当一个事务中有多个子事务时,子事务要么全部执行要么全部不执行,不会出现一部分事务执行另一部分不执行的情况,它们都属于一个原子,在生物学中原子是组成物质的最小单位,具有不可再分的特性,用原子性表示事务是一个有机的整体再好不过了。
一致性
事务执行的结果必须使数据库从一种状态到另一种状态。
隔离性
隔离性描述的是事务之间的特性,表示事务与事务之间互不影响,假如一个事务在对数据库表中一条数据做修改操作这时其他的事务不可以操作该条数据记录。即一个事务在未提交之前,它的结果不应该呈现给其他事务。
持久性
事务提交后,事务对数据库的操作结果会永久保存在数据库中。
多事务执行引起的问题
假设事务一个一个放到队列里面按照顺序执行,前一个事务执行完后后面的事务在执行,这样事务与事务之间不会产生影响不会引起别的问题,但问题是如果在多线程环境中多个事务共同执行就可能引发各种问题,其中带来的主要问题有如下四个:
脏读:
即A事务读取到了B事务未提交的数据,这样A事务读取到的数据就是错误的产生了脏读。
不可重复读:
如果A、B两个事务都操作同一条记录,当A事务读取完后,B事务对这条数据做了修改那么A事务再读取时读到的就是错误的数据,由此产生不可重复读问题。
虚读或幻读:
事务A查询符合某条件的数据记录,此时事务B又插入了一些符合这些条件的记录,如果事务A再次查询,查询出来的数据会多出一些,产生虚读现象。
解决办法:
如果一个事务在未提交之前,不允许其它事务对数据进行操作,则可以避免上述问题的产生。可以给事务增加锁机制如此一个事务在操作某些记录时,给这些记录加锁其他事务就不能够操作这些数据了。
尽管数据库为用户提供了锁的DML操作方式,但直接使用锁管理是非常麻烦的,因此数据库为用户提供了自动锁机制。只要用户指定会话的事务隔离级别,数据库就会分析事务中的SQL语句,然后自动为事务操作的数据资源添加上适合的锁。此外数据库还会维护这些锁,当一个资源上的锁数目太多时,自动进行锁升级以提高系统的运行性能,而这一过程对用户来说完全是透明的。
枷锁的目的完全隔离开了每个事务之间的影响,事务与事务之间互不影响,如果一个事务操作一个表数据而且时间很长,其他的事务就需要等待,这样会降低系统性能,系统资源得不到合理利用。
并发这块主要问题是解决事务之间的问题,而事务原则中隔离性描述的是事务之间关系,隔离性特性事务又给出了一些细分,以来控制多事务并发。
四种事务隔离级别
1.Read Uncommited: 读未提交的数据
2.Read commited: 读已提交的数据
3.Repeateble Read: 可重复读
4.Serialable: 序列化
上面四种隔离级别,从1-4隔离级别越来越严格,数据安全和真实性越来越高,但并发性能越来越低。所以选择什么样的隔离级别应根据应用的具体要求而定。对于多数应用程序,可以有优先考虑把数据库系统的隔离级别设为ReadCommited,它能够避免脏读,而且具有较好的并发性能。
EJB容器管理事务
EJB对事务的管理可以分为两种:EJB容器管理和EJB bean手动管理,开发中我们通常使用容器管理事务,相比手动管理容器管理简洁、灵活、易于维护。
只需在EJB类上加上注解声明就可以为ejb类增加事务的功能,类似与Spring AOP是一种声明式的事务管理机制。
在使用容器管理事务时,EJB 容器会拦截客户请求,并自动为EJB组建启动新的事务,也就是说,容器会通过begin 语句调用底层事务系统,从而启动事务。随后,容器会将业务请求委派给EJB组件,组件中的业务操作将运行在这一事务中。处于事务中的EJB 组件能够执行任何业务逻辑,如写入数据库、发送异步信息、调用其他的EJB组件等。一旦在处理业务过程中出现问题,则EJB 组建需要通知EJB 容器去回滚事务。当EJB 组建完成业务处理后,会将控制权交回给EJB 容器。随后,EJB容器能够通过commit 或abort 语句调用底层事务系统。
@Stateless @Remote(ITitleBean.class) @TransactionManagement(TransactionManagementType.CONTAINER) @TransactionAttribute(TransactionAttributeType.REQUIRED) public class TitleBeanImpl extends BaseMgr implements ITitleBean {
………………………………………………………………………………
}通过这两个注解就把该ejb类交给了容器管理,ejb容器会为该类提供事务服务。
<pre name="code" class="java">@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
用CMT管理事务,事务都是被容器管理的,开发人员不需要对事务进行管理,需要做的就是配置事务属性.
下一篇博客中将会介绍EJB中分布式事务是怎么管理。
EJB Container Manage Transaction