2012-01-11 43 views
0

我的应用程序部署在具有2个节点的weblogic 9群集环境中,并使用持久性提供程序toplink连接到MS SQL Server 2005。部署的应用程序是用Java编写的。在weblogic集群环境(群集内的多个节点)上工作时行锁定失败

我的应用程序需要的服务请求的时候做简单的操作:

  1. 开始交易
  2. 从表A和地方行选择项上他们锁定
  3. 处理它们
  4. 更新表A中结果。
  5. 结束交易

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在同一时间请求,双方节点将能够继续到第3步,这超出了我的预期。因为我期望数据库应该已经被节点锁定(例如节点1),所以首先经过步骤2(因为with(updlock, rowlock)),而后面的一个应该被阻塞直到第一个事务被提交。

我可以知道我是否有问题吗?非常感谢您的帮助你的回应


感谢。经过一番深入调查,我发现:

  1. 我们的方法实际上是由MDB
  2. 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

都会收到第3步和完整,第二个事务要等到第一个提交它经历虽然之前。

如果您没有看到它,这很奇怪。你确定第123行存在吗?他们是否连接到同一个数据库,您的事务配置是否正确?如果你尝试(updlock)它是否工作?这可能与您的数据库配置方式有关,也许在数据库shell中尝试相同。

而不是选择,你也可以尝试更新行(设置一些列等于自己),这应该确保获得行锁。

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”。

+0

非常感谢您的帮助! – 2012-02-14 10:05:55