`
wuhongyu
  • 浏览: 404440 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

EJB两阶段提交事物传播问题

阅读更多

    昨天改EJB程序时出现了一个bug,服务器报了一个transaction does not exist,研究了大半天,终于发现原来是因为我的两个事物同时修改一条记录,weblogic两阶段提交时产生的问题,先上代码(示例,不是真实那个啊):

 

第一个接口:

 

@Stateless
@Remote( { ARmote.class })
public class ABean implements ARmote{
	@EJB
	private ARmote aRmote;
	@EJB
	private BRmote bRmote;

	public void invoke(DTO dto){
		bRmote.update(dto);
		aRmote.update(dto);
	}
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public int update(DTO dto){
		return dao.update(dto);
	}
}

 第二个接口:

@Stateless
@Remote( { BRmote.class })
public class BBean implements BRmote{
	public int update(DTO dto){
		return dao.update(dto);
	}
}

 

 

    第一个接口和第二个接口分别改同一个表中不同的字段,当我调用ARemote的invoke方法时报错(别问问啥这么写,需求)。

    原因是:当程序执行到BRemote的update方法时,由于使用的是默认的事物级别(required),因此会加入ARemote的事物中,BRemote的update方法执行完毕后,weblogic会执行第一阶段提交;然后程序继续执行到aRmote.update(dto);这行时,又新起了一个事物,去操作刚刚修改的记录,导致oracle报错。

    后来将aRmote.update(dto);这行挪到BRemote的update方法中,虽然修改的也是这条记录,但程序不会出现问题。

    分析后得出如下结论:

    假设方法A内调用方法B,方法B内调用方法C,假设A、B使用REQUIRED级别、C使用REQUIRES_NEW级别的事物,这时,方法A、B在事物1中进行,方法C在事物2中进行,那么事物的出栈顺序为:

1、执行方法C之前,方法B内所做的数据库操作不进行提交。

2、方法C执行完毕后,事物2两阶段全部提交。

3、方法B执行完毕后,方法B内所做的数据库操作进行第一阶段提交。

4、方法A执行完毕后,方法A、B内所做的数据库操作进行两阶段端提交。


大致如下

 

  • 大小: 35.9 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics