0

即使在谷歌关于 jdo 数据存储事务的文档中,我也到处检查过,但找不到任何东西。我的问题是我有一个带有 ArrayList 的实体,有时这些项目会丢失或未正确保存。这是一个大问题,因为我在 PRODUCTION 中存在不一致和数据丢失。

父实体

@PersistenceCapable
public class Account

@Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "key ASC"))
private ArrayList<Match> matches = new ArrayList<Match>();

孩子

@PersistenceCapable
public class Match

@Persistent
private ArrayList<Long> players = new ArrayList<Long>();

现在,我有一个 cron 任务,每 15 分钟更新一次玩家数组列表。

PersistenceManager manager = PMFactory.get().getPersistenceManager();
List<Account> accounts = <<obtain all accounts>>
for (Account account : accounts) {
 Transaction tx = manager.currentTransaction();
 tx.begin();
 List<Long> players = account.getMatches.getPlayers();
    <<add or remove elements - players.remove()/players.add()>>
 tx.commit();
}
manager.close();

代码只是一个摘要。我尝试/捕获并记录所有内容。永远不会引发任何异常,并且任务可以正常完成。我无法在本地重现此错误。我有大约 300 个帐户,每个帐户可能有 10 个匹配项。比赛的球员不超过20人。只是有时球员名单没有正确更新......甚至他们失去了一些元素。大多数时候它都有效。也许当第二个或第三个实例出现时?我应该关闭持久性管理器并为每个帐户获取一个新的吗?我正在使用 jdo 2.3。使用这个应用程序已经 4 年了,但现在我有更多的开户,我遇到了这个问题。请让我绝望!:-( 提前谢谢了!

jdoconfig.xml

<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">

   <persistence-manager-factory name="transactions-optional">
       <property name="javax.jdo.PersistenceManagerFactoryClass"
           value="org.datanucleus.api.jdo.JDOPersistenceManagerFactory"/>
       <property name="javax.jdo.option.ConnectionURL" value="appengine"/>
       <property name="javax.jdo.option.NontransactionalRead" value="true"/>
       <property name="javax.jdo.option.NontransactionalWrite" value="true"/>
       <property name="javax.jdo.option.RetainValues" value="true"/>
       <property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
       <property name="datanucleus.appengine.datastoreEnableXGTransactions" value="true"/>
       <property name="datanucleus.appengine.singletonPMFForName" value="true"/>
   </persistence-manager-factory>
</jdoconfig>

持久性.xml

<persistence 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" version="1.0">

    <persistence-unit name="transactions-optional">
        <provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider>
        <properties>
            <property name="datanucleus.NontransactionalRead" value="true"/>
            <property name="datanucleus.NontransactionalWrite" value="true"/>
            <property name="datanucleus.ConnectionURL" value="appengine"/>
        </properties>
    </persistence-unit>
</persistence>
4

1 回答 1

0

我找到了一种让它发挥作用的方法。我不确切知道哪条线使它起作用,或者它是否是整体:

PersistenceManager manager = PMFactory.get().getPersistenceManager();// get instance of PM
List<Account> keys = <<obtain all accounts KEYS>> //get only KEYS(before I was getting all accounts and not by their keys)
manager.close(); // close PM

for (Key key : keys) {
  manager = PMFactory.get().getPersistenceManager();// get instance of PM for each account:  Is this necessary?? should I use the same PM as before?? 
  Account account = dao.getAccount(key);
  List<Long> players = account.getMatches.getPlayers();
    <<add elements(players.add()) or do nothing depending on business logic>>               
  manager.flush(); //flush: is this necessary??
  manager.close(); // close PM for each account
}

这段代码似乎有效。我不知道它的工作原理是关闭和打开每个帐户的 PM,还是获取 KEYS,然后通过其 KEY 获取每个帐户,或者在关闭 PM 之前刷新。由于我只能在 PRODUCTION 中重现此错误,因此我无法测试是什么使它起作用以及什么是不必要的。我知道这段代码有效。

于 2015-11-09T15:15:35.647 回答