Java 如何使用 Weblogic 10.3 从 JNDI 数据源获取 JDBC 连接以参与 UserTransaction?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1925556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get JDBC connections obtained from a JNDI datasource to participate in a UserTransaction using Weblogic 10.3?
提问by lucasweb
I am currently retrieving both a UserTransaction and a DataSource from a Weblogic 10.3 server using JNDI.
我目前正在使用 JNDI 从 Weblogic 10.3 服务器检索 UserTransaction 和 DataSource。
I have set the Datasource up to 'Support Global Transactions' and to use 'Logging Last Resource'
我已将数据源设置为“支持全局事务”并使用“记录上一个资源”
My hope was that by beginning a UserTranscation and then retrieving a JDBC connection from the Datasource the connection would participate in the Transaction.
我希望通过开始 UserTranscation 然后从数据源检索 JDBC 连接,该连接将参与事务。
This does not appear to be the case, and my insert statements are being commited straight away and rolling back the transaction does not have any effect.
情况似乎并非如此,我的插入语句正在立即提交,回滚事务没有任何效果。
Are my above assumptions correct?
我的上述假设是否正确?
Can anyone point me in the direction of some documentation or samples on how to achieve this?
任何人都可以向我指出有关如何实现这一目标的一些文档或示例的方向吗?
Many thanks in advance
提前谢谢了
UPDATE:
更新:
As requested here is a skeleton outline of the code I am using:
根据这里的要求,是我正在使用的代码的骨架大纲:
private void doSomething() {
Connection conn = null;
try {
Hashtable env = new java.util.Hashtable();
env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
env.put(javax.naming.Context.PROVIDER_URL,"t3://localhost:8080");
InitialContext ctx = InitialContext(env));
UserTransaction transaction = null;
transaction = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
DataSource dataSource = (DataSource) context.lookup("jdbc/xxxxx/DataSource");
conn = dataSource.getConnection();
transaction.begin();
// JDBC code goes here
transaction.commit();
} catch(Exception e) {
// TODO
if (transaction != null) {
try {
transaction.rollback();
} catch (Exception ex) {
// TODO
}
} finally {
if (con != null) {
conn.close
}
}
}
UPDATE 2:
更新 2:
In order to resolve this issue I had to do 2 things:
为了解决这个问题,我必须做两件事:
Change the order of the code to firstly begin the user transaction and then get a connection from the Datastore (as pointed out by Pascal Thivent).
Change the Datasource referenced by '"jdbc/xxxxx/DataSource"' to an XADatasource. This is because I was calling code inside the user transaction that used another Datasource that was already configured to support LLR and as pointed out by Pascal Thivent below you can only have one LLR Datasource participate in a transcation.
更改代码顺序以首先开始用户事务,然后从数据存储区获取连接(如 Pascal Thivent 所指出的)。
将 '"jdbc/xxxxx/DataSource"' 引用的数据源更改为 XADatasource。这是因为我在用户事务中调用了使用另一个已配置为支持 LLR 的数据源的代码,正如下面 Pascal Thivent 所指出的,您只能让一个 LLR 数据源参与事务。
I have accepted Pascal Thivent's answer below because it explained both of these issues.
我在下面接受了 Pascal Thivent 的回答,因为它解释了这两个问题。
采纳答案by Pascal Thivent
Yes, your assumptions are correct and, according to Create LLR-enabled JDBC data sources, your data source seems properly configured.
是的,您的假设是正确的,根据Create LLR-enabled JDBC data sources,您的数据源似乎已正确配置。
Do you get the connection after starting the user transaction? Can you show your code or pseudo code?
启动用户事务后是否获得连接?你能展示你的代码或伪代码吗?
UPDATE:As mentioned in Programming Considerations and Limitations for LLR Data Sources:
更新:如LLR 数据源的编程注意事项和限制中所述:
- When programming with an LLR data source, you must start the global transaction before calling getConnection on the LLR data source. If you call getConnection before starting the global transaction, all operations on the connection will be made outside of the global transaction.
- 使用 LLR 数据源编程时,必须在对 LLR 数据源调用 getConnection 之前启动全局事务。如果在启动全局事务之前调用 getConnection,则连接上的所有操作都将在全局事务之外进行。
So, could you try this:
所以,你能不能试试这个:
transaction.begin(); //start the global tx before calling getConnection()
conn = dataSource.getConnection();
...
transaction.commit();
UPDATE2:Not sure to understand from where the 2nd connection is comming (your pseudo code isn't showing this). However, according to the same Programming Considerations and Limitations for LLR Data Sources:
UPDATE2:不确定第二个连接是从哪里来的(你的伪代码没有显示这个)。但是,根据LLR 数据源的相同编程注意事项和限制:
- Only instances of a single LLR data source may participate in a particular transaction. A single LLR data source may have instances on multiple WebLogic servers, and two data sources are considered to be the same if they have the same configured name. If more than one LLR data source instance is detected and they are not instances of the same data source, the transaction manager will roll back the transaction.
- 只有单个 LLR 数据源的实例可以参与特定事务。单个 LLR 数据源可能在多个 WebLogic 服务器上有实例,如果两个数据源具有相同的配置名称,则认为它们是相同的。如果检测到多个 LLR 数据源实例并且它们不是同一数据源的实例,则事务管理器将回滚该事务。
Actually, without a fully representative example, I feel a bit like walking in the dark :)
其实,没有一个完全有代表性的例子,我感觉有点像在黑暗中行走:)