gpt4 book ai didi

database - Java UserTransaction 中的多个数据库连接

转载 作者:太空狗 更新时间:2023-10-30 01:59:57 25 4
gpt4 key购买 nike

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();
}
}
}

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

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

我把DAO层拿出来,把逻辑翻译成上面的代码。有一件事我无法理解,根据上面的代码,插入操作应该失败,因为代码(在 UserTransaction 内)采用两个不同的连接,它们彼此不认识,并且第一个删除显然没有提交,所以第二个语句(插入)应该失败(由于唯一约束),因为两个数据库操作不在同一个连接中,第二个连接无法检测到未提交的更改。但令人惊讶的是,它并没有失败,而且这两个语句都可以完美地工作。

谁能帮忙解释一下?可以做任何配置来实现这个结果吗?还是我的理解有误?

最佳答案

由于您的应用程序在 weblogic 服务器中运行,java-EE-container 正在为您管理事务和连接。如果您在 java-ee 事务中多次调用 DataSource#getConnection,您将获得多个加入同一事务的 Connection 实例。通常这些连接使用相同的 session 连接到数据库。使用 oracle,您可以在 @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

请注意,您会得到具有相同 session ID 的不同 Connection 实例。

有关更多详细信息,请参见例如 this question

关于database - Java UserTransaction 中的多个数据库连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38823693/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com