我的应用程序部署在具有2个节点的weblogic 9集群环境中,并使用持久性提供程序toplink连接到MS SQL Server 2005。部署的应用程序是用Java编写的。
我的应用程序在提供请求时需要做一个简单的操作A:
java代码如下:
EntityManager em =Persistence.createEntityManagerFactory("NewPersistenceLevelPU").createEntityManager;
EntityTransaction transaction = em.getTransaction();
transaction.begin();
// step 2
em.createNativeQuery("select * from Table_A with(updlock, rowlock) where id = 123");
List<List<Object>> results = (List<List<Object>>) query.getResultList();
//step 3
SomeOperation(results);
// step 4, using the results from step 3
em.createNativeQuery("update Table_A set Column A = 'something' where id = 123");
// step 4
em.flush();
transaction.commit();
似乎如果我同时在节点1和节点2上启动请求A,则两个节点都可以进入步骤3,这超出了我的预期。正如我所期望的那样,数据库应该已经被节点锁定(例如节点1)首先完成步骤2(因为with(updlock, rowlock)
),而后者应该被阻塞直到第一个事务被提交。
我可以知道我有什么问题吗?非常感谢您的帮助
感谢您的回复。经过一番调查后,我发现了以下内容:
persistence.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="NewPersistenceLevelPU" transaction-type="JTA">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<jta-data-source>TestDB</jta-data-source>
<properties>
<property name="toplink.cache.type.default" value="" />
</properties>
</persistence-unit>
</persistence>
所以我现在想知道: 1.它是应用程序管理的还是容器管理的事务管理器? 2.在这两种情况下,我如何处理应用程序内的事务?使用UserTransaction或EntityTransaction?
非常感谢
答案 0 :(得分:0)
两者都将进入第3步并完成,第二个事务应该等到第一个提交才会通过。
如果你没有看到这个,那就太奇了。你确定第123行存在吗?他们是否连接到同一个数据库,您是否正确配置了事务?如果您尝试使用(updlock)它是否有效?它可能与数据库的配置方式有关,也可能在数据库shell中尝试相同。
您可以尝试更新行(将某些列设置为等于自身),而不是select,这应该确保获取行锁。
答案 1 :(得分:0)
从您的persistence.xml中使用JTA事务,但是从您的代码中使用的是JPA EntityManager事务。你不能同时使用这两者。
如果您使用的是MDB,则应使用注入的JTA托管EntityManager。您不应该使用JPA事务,MDB应该自动启动/结束JTA事务。
我的猜测是你没有设置“toplink.target-server”,你必须这样做才能在WLS上启用JTA集成。我不确定TopLink Essentials是否提供了WLS服务器,因此您可能希望升级到EclipseLink。
如果要使用JPA EntityManager事务,请在persistence.xml中设置transaction-type =“RESOURCE_LOCAL”。