日期:2014-05-18  浏览次数:20770 次

EJB容器管理事务,不回滚
代码如下:

@Stateless
@Remote
@TransactionManagement(TransactionManagementType.CONTAINER)
public class RoleBeanImpl implements IRoleBean {

@Resource
private SessionContext context;

@Resource(mappedName = "common_EaoBean/remote")
private ICommonEao commonEao;

@Resource(mappedName = "public_QueryBean/remote")
private IPublicQuery publicQueryEao;

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void addRole1(Role role) {
System.out.println("----------------RoleBeanImpl.addRole------------");
commonEao.save(role);
throw new EJBException();  //这里抛异常,上句应该回滚,实际没有回滚
}


@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void addRole2(Role role) {
try {
commonEao.save(role); //向数据库中插入一条记录,如果后面报异常,这句应该回滚,但实际没有回滚

Role role1 = new Role();//新建一个空的role
commonEao.save(role1);//这句抛异常,但是前面插入的role不回滚,插入成功
System.out.println("----------------RoleBeanImpl.modifyRole------------");
} catch (Exception e) {
e.printStackTrace();
context.setRollbackOnly();
}
}





客户端调用
public static void main(String args[]) {

try {
Properties props = new Properties();
// 设置JNDI驱动的类名
props.setProperty("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
// 提供命名服务的URL
props.setProperty("java.naming.provider.url", "192.168.24.12:1099");
InitialContext ctx = new InitialContext(props);
IRoleBean roleBean = (IRoleBean) ctx.lookup("RoleBeanImpl/remote");
 
Role role=new Role();
role.setName("555");
roleBean.addRole(role);


} catch (NamingException e) {
System.out.println(e.getMessage());
}
}



主要问题,
手动抛 EJBException(),不回滚。
截获异常,手动context.setRollbackOnly();依然不回滚

见代码注释。该回滚的地方没有回滚,不明白为什么。


环境:
jboss 5.1.0
jdk 1.6
oracle 11g



------解决方案--------------------
你可以检查一下ICommonEao 这个EJB里的save方法,如果事务传播属性为Required,或者Supports时才可被回滚。其他属性不回滚是正确的。
------解决方案--------------------
    @Resource(mappedName = "common_EaoBean/remote")
    private ICommonEao commonEao;

@Stateless(name = "common_EaoBean")
@Local
@TransactionManagement(Transacti