EJB事务的讨论

09-08-26 windgoogle
一个容器管理事务的无状态会话Bean,事务属性为Required
业务方法线程sleep了15 s,应用服务器交易超时为10s,

public void insertData() {
try {
Connection connection = connection();
Statement stmt = connection.createStatement();
String upd = "insert into student(stuid,stu_name) values('98','sdsd')";
try{
Thread.sleep(15*1000);
}catch(Exception e){
e.printStackTrace();
}
stmt.execute(upd);

} catch (Exception e) {
e.printStackTrace();
}finally{

System.out.println("rollback only? "+ctx.getRollbackOnly());
}
}

按道理这个事务会交易超时导致回滚,但是实际却不是这样的,在weblogic9上,交易却没回滚,数据库记录还是插入了,SUN的应用服务器也是这样,当然都调了事务超时时间为10s,百思不得其解

banq
2009-08-26 17:18
在EJB中不要直接使用线程。特别是事务,因为事务也是依靠线程实现的。
你使用线程,破坏了EJB底层线程调用策略,所以出现不正常现象。

windgoogle
2009-08-26 17:51
老大,只是用了Thread.sleep()而已。这当然不是生产环境里的真实应用,就是为了模拟事务超时啊,看应用服务器的这个事务超时配置起不起作用啊,事务超时,事务管理器应该回滚这个事务的

banq
2009-08-26 18:26
你为了模拟,可以使用throw new Exception就可以了。

另外取决于数据源JNDI的配置。需要使用服务器的数据源JNDI。

windgoogle
2009-08-26 18:55
老大,throw new Exception是模拟异常引起的事务回滚,按EJB规范,系统异常才能引起事务回滚,我需要模拟,事务执行时间过长引起的事务超时导致事务回滚的,服务器数据源和直接获取数据库连接有什么差别吗,我测了,效果是一样的

banq
2009-08-26 19:06
>时间过长引起
用while循环

windgoogle
2009-08-27 09:55
用下面这段代替Thread.sleep(),效果还是一样的
long n=0;
long now=System.currentTimeMillis();
long nextTime=now;
while(n<=30*1000){
nextTime=System.currentTimeMillis();
n=nextTime-now;
}

按道理事务应该回滚的,结果是大多应用服务器都没回滚,有的有回滚信息提示,但是数据库记录还是插入了,有的压根就没有回滚信息提示,百思不得其解

[该贴被windgoogle于2009-08-27 09:57修改过]

banq
2009-08-27 11:12
这种情况自己编程定义

所以,这时面向并发线程编程就显示其对待特殊问题的方便性,JavaEE/EJB只是面向普通问题域提出的共性解决方案。共性就失去特性。