EJB方法抛异常,事务怎么没有回滚  

EJB中的方法,如果ID传“111111”方法会抛出CreateException,EJB部署的是:
<container-transaction>
<method>
<ejb-name>PdUserSession</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
但抛异常后,数据还是插到数据库中了,为什么不回滚!!
public void createUser(String id, String pass, String first, String last, String group) throws NamingException, CreateException {
DataSource ds = (DataSource) EjbHomeFactory.lookup("DataSource");
try {
Connection con = ds.getConnection();
PreparedStatement ps = con.prepareStatement(
"insert into pd_user(id) values ('" + id + "')");
ps.executeUpdate();

}
catch (SQLException ex) {
ex.printStackTrace();
}
if(id.indexOf("1") > -1){
throw new CreateException();
}

}
如果改成BEAN管理事务的,就可以了,难道上面的那个事务没起来
public void createUser(String id, String pass, String first, String last, String group) throws NamingException, CreateException {
/**@todo Complete this method*/
UserTransaction tx = sessionContext.getUserTransaction();
try {
System.out.println("===========begin============");
tx.begin();
/*
String description = "Demo Description";
String rgyName = "cn=" + id + "," + PdHelper.rgySuffix;
PDRgyUserName pdRgyUserName =
new PDRgyUserName(rgyName, first, last);
boolean ssoUser = false;
boolean pwdPolicy = true;
ArrayList groupList = new ArrayList();
groupList.add(group);

System.out.println("Creating a user...\n");
PDUser.createUser(ContextFactory.getContext(),
id,
pdRgyUserName,
description,
pass.toCharArray(),
groupList,
ssoUser,
pwdPolicy,
new PDMessages());

*/
DataSource ds = (DataSource) EjbHomeFactory.lookup("DataSource");

Connection con = ds.getConnection();
PreparedStatement ps = con.prepareStatement(
"insert into pd_user(id) values ('" + id + "')");
ps.executeUpdate();

//PdUserHome home = (PdUserHome) EjbHomeFactory.lookup("PdUser");
//PdUser user = home.create(id, pass, first, last, group);

}
catch (Exception ex1) {
ex1.printStackTrace();
}
finally{
System.out.println("fianlly======================");
try {
if(id.indexOf("1") > -1){
System.out.println("rollback======================");
tx.rollback();
}else{
tx.commit();
}

}
catch (Exception ex) {
ex.printStackTrace();
}

}
}

还是我理解的有问题

你的第一种情况是JDBC的方式, JDBC默认的事务为自动提交,也就是说执行完ps.executeUpdate();后就已经入库了,你再throw exception也无力回天了, 你如果把JDBC事务改为手动提交,在代码


DataSource ds = (DataSource) EjbHomeFactory.lookup("DataSource");
try {
Connection con = ds.getConnection();
conn.setAutoCommit(false);
PreparedStatement ps = con.prepareStatement(
"insert into pd_user(id) values ('" + id + "')");
ps.executeUpdate();

}
catch (SQLException ex) {
ex.printStackTrace();
}

if(id.indexOf("1") > -1){
throw new CreateException();
}
conn.commit();

就不会出现你那种情况了.

我们以前做的类似PETSTORE后台的EVENT,EJB中调DAO,DAO里面并没有对JDBC的事务做设置,事务是可以回滚的
EJB中的JDBC事务难道还要另设吗,EJB的事务用来做什么呢
我现在做TIVOLI的整合,用户的一部分信息是在IBM Directory Server中的,另外一些在自己的数据库中, 自己数据库中用ENTITY BEAN,IBM Directory Server的用户操作提高API,要先建一个CONTEXT,新建用户时有个2段提交的问题,用EJB的事务保证数据的完整,但不管用哪种事务控制(BEAN或容器)IBM Directory Server都不能回滚,EJB 控制不了吗,哪有什么好的办法 吗

:((((
那么谁能说说在整合多个系统时,怎样保证事务完整

It depends on what ever configuration you set in EJB.

<<EJB中调DAO,DAO里面并没有对JDBC的事务做设置,事务是可以回滚的
EJB中的JDBC事务难道还要另设吗,EJB的事务用来做什么呢<<

If you set CMT in EJB's method, you definitly don't need demarcate transaction in JDBC codes. CMT will help you automatically. You also could throw exception in CMT, 但不是用throw exception的方法, 而是用setRollbackOnly方法.

同理, 在BMT中, 不要仅仅就抛个例外, 在此之前,要先Rollback.

谢谢bruce
如果想用容器管理事务的话要么抛出一个系统级异常回退要么就是在捕捉到非系统级异常时使用contxt.setRollBackOnly()来回退
这样数据库的事务可以回滚,但是IBM DICTIONARY SERVER的事务还是不能回滚,我把2部分写到一个方法里,IBM DICTIONARY SERVER里的用户已经创建,没有回滚:((本以为这种情况下EJB可以大显身手了,还是我的理解有错

try {
String description = "Demo Description";
String rgyName = "cn=" + id + "," + PdHelper.rgySuffix;
PDRgyUserName pdRgyUserName =
new PDRgyUserName(rgyName, first, last);
boolean ssoUser = false;
boolean pwdPolicy = true;
ArrayList groupList = new ArrayList();
groupList.add(group);

System.out.println("Creating a user...\n");
PDUser.createUser(ContextFactory.getContext(),
id,
pdRgyUserName,
description,
pass.toCharArray(),
groupList,
ssoUser,
pwdPolicy,
new PDMessages());
PdUserHome home = (PdUserHome) EjbHomeFactory.lookup("PdUser");
PdUser user = home.create(id, pass, first, last, group);

if(id.indexOf("1") > -1){
throw new Exception();
}
}
catch (Exception ex1) {
this.sessionContext.setRollbackOnly();
ex1.printStackTrace();
}



try {
String description = "Demo Description";
String rgyName = "cn=" + id + "," + PdHelper.rgySuffix;
PDRgyUserName pdRgyUserName =
new PDRgyUserName(rgyName, first, last);
boolean ssoUser = false;
boolean pwdPolicy = true;
ArrayList groupList = new ArrayList();
groupList.add(group);

System.out.println("Creating a user...\n");
PDUser.createUser(ContextFactory.getContext(),
id,
pdRgyUserName,
description,
pass.toCharArray(),
groupList,
ssoUser,
pwdPolicy,
new PDMessages());
PdUserHome home = (PdUserHome) EjbHomeFactory.lookup("PdUser");
PdUser user = home.create(id, pass, first, last, group);

if(id.indexOf("1") > -1){
throw new Exception();
}
}
catch (Exception ex1) {
this.sessionContext.setRollbackOnly();
ex1.printStackTrace();
}finally{
this.sessionContext.setRollbackOnly();
}

如果这样事务还不能rollback的话,那就没办法了(没用过IBM DICTIONARY SERVER), 不过你可以再换个SQL Server, Oracle什么的再试试。 It doesn't make sense! !