Java中多个DB连接在UserTransaction中 [英] Java more than one DB connection in UserTransaction

查看:928
本文介绍了Java中多个DB连接在UserTransaction中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

static void clean() throws Exception {
  final UserTransaction tx = InitialContext.doLookup("UserTransaction");
  tx.begin();

  try {
    final DataSource ds = InitialContext.doLookup(Databases.ADMIN);
    Connection connection1 = ds.getConnection();
    Connection connection2 = ds.getConnection();
    PreparedStatement st1 = connection1.prepareStatement("XXX delete records XXX"); // delete data

    PreparedStatement st2 = connection2.prepareStatement("XXX insert records XXX"); // insert new data that is same primary as deleted data above

    st1.executeUpdate();
    st1.close();
    connection1.close();
    st2.executeUpdate();
    st2.close();
    connection2.close();
    tx.commit();
  } finally {
    if (tx.getStatus() == Status.STATUS_ACTIVE) {
      tx.rollback();
    }
  }
}



我有一个网络应用程序, DAO DataSource 作为创建单独连接以执行数据库操作的对象。

I have a web app, the DAO taking DataSource as the object to create individual connection to perform database operations.

所以我有一个 UserTransaction ,里面有两个 DAO 对象做分开的动作,一个是删除,第二个是插入。删除是删除一些记录以允许插入,因为插入将插入相同的主键的数据。

So I have a UserTransaction, inside there are two DAO object doing separated action, first one is doing deletion and second one is doing insertion. The deletion is to delete some records to allow insertion to take place because insertion will insert same primary key's data.

我取出 DAO 层并将逻辑转换为上面的代码。有一件事我不能理解,基于上面的代码,插入操作应该失败,因为代码( UserTransaction )采取两个不同的连接,他们因为第二个语句(插入)应该失败(由于唯一约束),因为两个数据库操作不在同一个连接中,第二个连接不能检测未提交的更改。但令人惊讶的是,它不会失败,这两个语句都可以完美地工作。

I take out the DAO layer and translate the logic into the code above. There is one thing I couldn't understand, based on the code above, the insertion operation should fail, because the code (inside the UserTransaction) take two different connections, they don't know each other, and the first deletion haven't committed obviously, so second statement (insertion) should fail (due to unique constraint), because two database operation not in same connection, second connection is not able to detect uncommitted changes. But amazingly, it doesn't fail, and both statement can work perfectly.

任何人都可以帮助解释这个?可以做任何配置来实现这个结果?

Can anyone help explain this? Any configuration can be done to achieve this result? Or whether my understanding is wrong?

推荐答案

由于您的应用程序正在weblogic服务器中运行,因此java-EE-容器正在管理事务和连接为您。如果在java-ee事务中多次调用 DataSource#getConnection ,您将获得多个 Connection 实例交易。通常这些连接连接到具有相同会话的数据库。使用oracle,您可以在 @Stateless ejb中检查以下片段:

Since your application is running in weblogic server, the java-EE-container is managing the transaction and the connection for you. If you call DataSource#getConnection multiple times in a java-ee transaction, you will get multiple Connection instances joining the same transaction. Usually those connections connect to database with the identical session. Using oracle you can check that with the following snippet in a @Stateless ejb:

@Resource(lookup="jdbc/myDS")
private DataSource ds;

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@Schedule(hour="*", minute="*", second="42")
public void testDatasource() throws SQLException {

    try ( Connection con1 = ds.getConnection();
          Connection con2 = ds.getConnection();
        ) {

        String sessId1 = null, sessId2 = null;
        try (ResultSet rs1 = con1.createStatement().executeQuery("select userenv('SESSIONID') from dual") ){
            if ( rs1.next() ) sessId1 = rs1.getString(1);
        };
        try (ResultSet rs2 = con2.createStatement().executeQuery("select userenv('SESSIONID') from dual") ){
            if ( rs2.next() ) sessId2 = rs2.getString(1);
        };

        LOG.log( Level.INFO," con1={0}, con2={1}, sessId1={2}, sessId2={3}"
               , new Object[]{ con1, con2, sessId1, sessId2}
               );
    }

}

讯息:

con1=com.sun.gjc.spi.jdbc40.ConnectionWrapper40@19f32aa, 
con2=com.sun.gjc.spi.jdbc40.ConnectionWrapper40@1cb42e0, 
sessId1=9347407, 
sessId2=9347407


b $ b

请注意,您获得的会话ID相同的连接实例。

有关详细信息请参阅此问题

这篇关于Java中多个DB连接在UserTransaction中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆