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

时间:2021-12-25 09:24:29
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();
    }

  }

17 个解决方案

#1


因为抛出CreateException的地方已经在SQL执行以后了,当然不会回滚。
解决方法:
//打开事务。
if(id.indexOf("1") > -1){
      //在这里回滚事务。
      throw new CreateException();
    }
else
    //提交事务。

当然,前面需要打开一个事务。

#2


这样不就成了BEAN管理事务了吗?我想把所有的事务都交给容器管理,不行吗?

#3


在catch (SQLException ex) 里面把exceptin抛出来。
catch (SQLException ex) {
    ex.printStackTrace();
    throw new CreateException();
}

#4


如果有SQLException的话,一般是操作失败
但我是想让已经成功的操作回滚

#5


ps.executeUpdate();有一个返回值,你根据它判断一下,来个throw new CreateException();不就行了。

#6


不是那个意思了,我现在关心的是不管操作是否成功,如果ID含1的话,肯定有异常的,如果成功了,有异常抛出,怎样回滚

#7


你的这段代码不可能实现数据库的会滚
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();
    }

  }
可以改为
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();
    con.setAutoCommit(false);
    PreparedStatement ps = con.prepareStatement(
        "insert into pd_user(id) values ('" + id + "')");
    ps.executeUpdate();
    if(id.indexOf("1") > -1){
      con.rollback();
      throw new CreateException();
    }else{
       con.commit();
    }

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

  }

#8


我知道Connection 可以控制数据库事务,但我是想让EJB容器来管理事务
如果上面执行的不是数据库操作呢,或者第三方只有API的操作,但无法控制事务怎么办

#9


在ejb-jar.xml设置此方法的Transaction为required.

#10


搞什么飞机?
CMT要
首先,你的驱动要支持JTA.
其次,要建一个TX数据源.
然后,要抛EJBException.

就可以拉

#11


要注意的是必须用tx的数据源,不可以用DriverManager直接拿connection, 否则容器的resource manager无法管理这个connection的资源,当然也就无法控制rollback和commit.

另外,如果分布式的transaction control,你的jdbc driver需要支持XA两阶段提交。目前Oracle支持最好,其他的都很麻烦,有的还要许可证。

#12


搞定了,如果想用容器管理事务的话要么抛出一个系统级异常回退要么就是在捕捉到非系统级异常时使用contxt.setRollBackOnly()来回退

我现在做TIVOLI的整合,用户的一部分信息是在IBM Directory Server中的,另外一些在自己的数据库中, 自己数据库中用ENTITY BEAN,IBM Directory Server的用户操作提高API,要先建一个CONTEXT,新建用户时有个2段提交的问题,数据库的事务可以回滚,但是IBM DICTIONARY SERVER的事务还是不能回滚,我把2部分写到一个方法里,IBM DICTIONARY SERVER里的用户已经创建,没有回滚
DanielYWoo(绿色毒汁) ,IBM DICTIONARY SERVER里的操作能回滚吗

#13


agree

#14


学习

#15


IBM DICTIONARY SERVER我没有用过,这个我就不懂得啦,你查一查文挡把,爱莫能助

#16


我搞不懂你为什么非得要插入数据库之后再回滚!
if(id.indexOf("1") > -1) 完全可以在createUser之前判断!

#17


jkit(郁闷之堕落的程序员) :呵呵,只是为了测试,故意让他回滚的
结贴,希望大家继续讨论
如果不是IBM DICTIONARY SERVER,其他的应用呢,必须实现X/Open XA protocol才能有JTA控制事务吗

#1


因为抛出CreateException的地方已经在SQL执行以后了,当然不会回滚。
解决方法:
//打开事务。
if(id.indexOf("1") > -1){
      //在这里回滚事务。
      throw new CreateException();
    }
else
    //提交事务。

当然,前面需要打开一个事务。

#2


这样不就成了BEAN管理事务了吗?我想把所有的事务都交给容器管理,不行吗?

#3


在catch (SQLException ex) 里面把exceptin抛出来。
catch (SQLException ex) {
    ex.printStackTrace();
    throw new CreateException();
}

#4


如果有SQLException的话,一般是操作失败
但我是想让已经成功的操作回滚

#5


ps.executeUpdate();有一个返回值,你根据它判断一下,来个throw new CreateException();不就行了。

#6


不是那个意思了,我现在关心的是不管操作是否成功,如果ID含1的话,肯定有异常的,如果成功了,有异常抛出,怎样回滚

#7


你的这段代码不可能实现数据库的会滚
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();
    }

  }
可以改为
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();
    con.setAutoCommit(false);
    PreparedStatement ps = con.prepareStatement(
        "insert into pd_user(id) values ('" + id + "')");
    ps.executeUpdate();
    if(id.indexOf("1") > -1){
      con.rollback();
      throw new CreateException();
    }else{
       con.commit();
    }

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

  }

#8


我知道Connection 可以控制数据库事务,但我是想让EJB容器来管理事务
如果上面执行的不是数据库操作呢,或者第三方只有API的操作,但无法控制事务怎么办

#9


在ejb-jar.xml设置此方法的Transaction为required.

#10


搞什么飞机?
CMT要
首先,你的驱动要支持JTA.
其次,要建一个TX数据源.
然后,要抛EJBException.

就可以拉

#11


要注意的是必须用tx的数据源,不可以用DriverManager直接拿connection, 否则容器的resource manager无法管理这个connection的资源,当然也就无法控制rollback和commit.

另外,如果分布式的transaction control,你的jdbc driver需要支持XA两阶段提交。目前Oracle支持最好,其他的都很麻烦,有的还要许可证。

#12


搞定了,如果想用容器管理事务的话要么抛出一个系统级异常回退要么就是在捕捉到非系统级异常时使用contxt.setRollBackOnly()来回退

我现在做TIVOLI的整合,用户的一部分信息是在IBM Directory Server中的,另外一些在自己的数据库中, 自己数据库中用ENTITY BEAN,IBM Directory Server的用户操作提高API,要先建一个CONTEXT,新建用户时有个2段提交的问题,数据库的事务可以回滚,但是IBM DICTIONARY SERVER的事务还是不能回滚,我把2部分写到一个方法里,IBM DICTIONARY SERVER里的用户已经创建,没有回滚
DanielYWoo(绿色毒汁) ,IBM DICTIONARY SERVER里的操作能回滚吗

#13


agree

#14


学习

#15


IBM DICTIONARY SERVER我没有用过,这个我就不懂得啦,你查一查文挡把,爱莫能助

#16


我搞不懂你为什么非得要插入数据库之后再回滚!
if(id.indexOf("1") > -1) 完全可以在createUser之前判断!

#17


jkit(郁闷之堕落的程序员) :呵呵,只是为了测试,故意让他回滚的
结贴,希望大家继续讨论
如果不是IBM DICTIONARY SERVER,其他的应用呢,必须实现X/Open XA protocol才能有JTA控制事务吗