在weblogic集群环境(集群内的多个节点)上工作时,行锁定失败

时间:2012-01-11 14:06:42

标签: sql jpa weblogic

我的应用程序部署在具有2个节点的weblogic 9集群环境中,并使用持久性提供程序toplink连接到MS SQL Server 2005。部署的应用程序是用Java编写的。

我的应用程序在提供请求时需要做一个简单的操作A:

  1. 开始交易
  2. 从表A中选择条目并在其上放置行锁定
  3. 处理它们
  4. 使用结果更新表A.
  5. 结束交易
  6. 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)),而后者应该被阻塞直到第一个事务被提交。

    我可以知道我有什么问题吗?非常感谢您的帮助


    感谢您的回复。经过一番调查后,我发现了以下内容:

    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>
      
    3. 所以我现在想知道: 1.它是应用程序管理的还是容器管理的事务管理器? 2.在这两种情况下,我如何处理应用程序内的事务?使用UserTransaction或EntityTransaction?

      非常感谢

2 个答案:

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