分享
 
 
 

masterEjb 2读书笔记——Transaction部分(1)

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

基本概念和词汇:

n Transaction object (or Transaction component): 是一个参与在事务当中的组件。如:Ejb 组件、.Net组件、Corba组件等。

n Transaction manager: 负责管理Transaction objects的事务操作。就像乐队中的指挥一样。

n Resource:持久的数据源。如:数据库、消息队列等。

n Resource manager: Resource的管理者,负责管理所有持久数据的状态。Resource manager的一个例子就是数据库、消息队列或其他存储器的驱动,最流行的Resource manager的接口就是X/Open XA resource manager接口。很多数据库驱动都支持这种接口,XA 事实上已经是Resource manager的工业标准。

n ACID (atomicity, consistency, isolation, durability): 一个事务肯定会由数据库给予四种担保,他们是:原子性atomicity, 一致性consistency, 隔离性isolation, 持久性durability。

Transaction models. 事务一般有两种模型:扁平(flat)事务和嵌套(nested)事务。当前的Ejb规范只支持扁平事务而不支持嵌套事务。

n 扁平事务模型:就是将一系列操作视为一个操作。事务开始之后,程序可以做任意多的操作,可以是持久化的操作也可以不是。这种模型的特点是:如果事务能够正常结束则将所有操作持久化,否则所有操作都不会被持久化。

n 嵌套事务模型:将原子事务操作嵌套入其他事务操作中。一个小事务块回滚不会导致整个事务回滚。而大的事务块可以重试失败了的小事务块。你可以将嵌套事务模型想象为一个树状模型,最大的事务块是树根,小的事务块是树叶,叶结点回滚不会影响他的父结点。

Ejb中的Transaction。

n EJBean会很自然的被事务化,他是做那种要求严格的系统的一个很好的选择。

n 在ejb中,Transaction会被抽象化、底层化,你的代码不可能与Transaction manager或Resource manager交互。底层的事务控制被容器抽象化了,你的程序只要决定是否提交或回滚即可。

n 我们必须提供一些关键信息给容器,告诉他谁开始了事务、谁会提交或回滚事务、这些步骤何时发生。这被称作“划分事务边界”。有三种划分事务的方法:

1. 程序控制(Programmatic Transaction):事务都是由程序来控制,程序中显式的调用begin、commit、rollback等方法。

2. 容器控制(Declarative Transaction):容器截取程序控制权然后自动调用begin开始事务,然后将控制权交还给Bean,这时bean可以做任何逻辑业务操作,如果程序遇到问题可以给容器发送失败信号,在Bean完成操作之后会将控制权交还给容器,这时容器决定是否commit或rollback。你可以在Deploy descriptor配置文件加入以下这句话来指出使用上述那种控制方式:

<transaction-type>Container</transaction-type>

这句话指出由容器来做事务控制,如果将Container替换为Bean,则由程序来控制事务。

3. 客户端控制(Client initiated transaction):可以在Bean的客户端程序中控制事务,如:jsp、servlet、applet或其他ejb等。但是要注意还是要在配置文件中指出被调用的Bean是使用Programmatic Transaction还是Declarative Transaction。

n Transaction and Entity Bean

l 当你在transaction中调用Entity Bean时,容器首先调用Bean中的ejbLoad()方法从数据库中得到数据,实际就是从数据库得到数据锁并且确定数据是否与缓冲池中的一致。然后调用若干个业务逻辑方法,当事务被提交之后,ejbStore()方法被调用,他将所有更改过的数据写入数据库并且释放锁。

l 为什么Entity Bean只能使用Container-managed transaction?而Bean-managed transaction只能用于session bean或message-driven bean?这是因为:对于bean-managed transaction来说,你必须显式的调用begin()或commit()方法,在Entity bean中你可能会在ejbLoad()中开始事务,并且在ejbStore()中提交事务。但问题是,这两个方法只能由容器调用,所以bean不能确定这两个方法何时会被调用,也就是说你在ejbLoad()方法中开始了事务,或许这个事务永远也不会被结束。而session bean和message-driven bean中可以随意控制数据的操作,所以不存在这个问题。

l Entity bean不会在每一个方法被调用的时候去读写数据库,而是在一个事务之中。所以如果你的程序写的不好,每一个函数调用的时候都开始一个事务,那么每次调用这些函数的时候都会读写一次数据库!解决的办法是让多个函数处于一个事务当中,在配置文件中你可以配置这些。

n 程序控制、容器控制、客户端控制这三种事务控制方法我们到底应该选择哪一个呢?他们都各自有各自的优点:

l 程序控制:优点就是你可以在你的Bean中完全控制事务。比如,你可以在一个函数中运行多个小的事务;但是对于容器控制或客户端控制事务的Entity Bean中的函数却只能要么启动一个事务要么就一个都不能启动。

l 容器控制:优点就是很简单。可以减少代码量并且不用更改代码就可以调整事务。

l 客户端控制:举一个例子来说明这种控制方式的优点。假如一个没有客户端事务控制远程用户想要调用一个EJB,这个EJB有自己的事务控制。如果这个Bean的事务完成了,但是在操作结果返回给客户端的时候网络或者服务器瘫痪了,这是java就会给客户端抛出一个RMI的RemoteException来告诉客户端网络出故障了。但是这样的话客户端不会知道Bean的事物是否成功结束,这是客户端就要写代码去知道事务是否成功,而这些代码是非常繁琐并且很容易出错,因为网络的故障有可能客户端永远也连接不到服务器端了。客户端控制的事务的好处就是可以解决这个问题。但是,如果客户端远离服务器端的时候,要少用这种控制方式,因为如果距离太远,那么事务回滚的时候很有可能引起冲突。

n 容器控制的事务

l 我们必须提供一些事务属性(Transaction attribution)来告诉容器怎样控制事务。可以给每个Bean以不同的事务属性。这些属性定义在Deployment description中,而且你可以为Bean定义属性也可以为Bean中的某个函数定义属性,如果你对两者都定义了事务属性,则函数定义的属性优先。

l 对于Message-Driven Bean来说,建议最好使用容器控制的事务。

l 以下是事务属性值的解释:

u Required:必须使用事务,如果在这个Bean外面已经有了一个事务,那么就加入到这个事务当中;否则就开始一个新的事务。

u RequiresNew:无论外界是否有事务,都启动一个新的事务。

u Supports:如果外界已经有事务,则加入这个事务;否则,不会启动新的事务。

u Mandatory:规定Bean的函数被调用的时候必须已经启动了一个事务,否则会抛出TransactionRequiredException。

u NotSupported:Bean不会被事务控制。如果在调用Bean之前已经启动了一个事务,那么这个事务会被暂时挂起,直到Bean结束之后事务才会继续。

u Never:Bean不能进入事务,如果在一个事务中调用这个Bean的话会抛出RomoteException。

l 注意:不同类型的Bean不一定支持上述所有类型的属性值。如:Entiry Bean和带有SessionSyncronization的Stateful SessionBean不支持Never, NotSupported, Supports属性;而Message-driven Bean不支持Never, Supports, RequiresNew, Mandatory属性。

n Ejb程序控制的事务

l 程序控制的事务要比容器控制的事务更加灵活,但是比较繁琐。而且必须要使用Java Transaction API(JTA)。

l Object Management Group(OMG)组织定义了一个标准Object Transaction Service(OTS)在事务的底层做了很多工作,使得我们的代码就简单多了,并且不用关心底层的操作。

l Sun公司将OTS在Java语言中分成了两块:Java Transaction Service(JTS)和Java Transaction API(JTA)。其中JTS是给系统级的厂商使用的,它帮助我们做了很多底层的复杂的工作;而用户只要使用JTA就可以了。

l JTA分为两组接口:一组给X/Open XA resource manager使用;一组给用户使用。用户主要使用javax.transaction.UserTransaction接口。

l UserTransaction接口共有六个方法:being(), commit(), rollback(), getStatus(), setRollBackOnly(), setTransactionTimeout()。使用Context.getUserTransaction()可以得到UserTransaction。

l 如果想让程序控制事务则必须在Deployment descriptor中将<transaction-type>置为Bean

l 当我们在程序中启动一个事务时,最好在同一个方法中结束这个事务,否则长时间打开事务会严重消耗系统资源。

l 如果一个函数处在一个已经被其他Bean创建好了的事务中,那么这个函数怎样才能销毁这个事务呢?

u 在容器控制的事务中,不能通过抛出异常的手段来销毁事务,因为你抛出的异常有可能是你自己定义的异常,容器无法知道你自己定义的异常是否严重到要销毁事务的程度。所以因该使用Context.setRollBackOnly()方法来结束事务。

u 如果这个函数是一个普通的java object,则可以先找到JTA,然后调用setRollBackOnly()方法来结束事务。

u 在一个事务中如果有十个Bean,其中第二个Bean发现错误并且作了setRollBackOnly()操作,那么剩余的几个Bean就不能再做相同的操作,因为这样会大量的消耗资源。而应该得到当前事务的状态,根据这个状态来进行操作。得到事务状态的方法有两种:如果是容器管理的事务使用getRollbackOnly()方法;如果是程序控制的事务使用getStatus()方法。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有