I've checked everywhere even in google's documentation on jdo datastores transactions but could not find anything. My problem is that I have an entity with an ArrayList and sometimes the items are lost or not correctly saved. This is a huge problem since I am having inconsistency and data lost in PRODUCTION.
Parent entity:
@PersistenceCapable
public class Account
@Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "key ASC"))
private ArrayList<Match> matches = new ArrayList<Match>();
Child:
@PersistenceCapable
public class Match
@Persistent
private ArrayList<Long> players = new ArrayList<Long>();
Now, I have a cron task that updates players array list every 15 minutes.
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();
The code is just a summary. I try/catch and log everything. NO exceptions raised never and task finishes OK. I can not reproduce this error on local. I have aprox 300 accounts with maybe 10 matches each. Players for match are no more than 20. Only sometimes players list are not correctly updated...or even they lose some elements. Most of the time it works. Maybe when a second or third instance comes to life?? Should I close persistence manager and get a new one for each account? Im using jdo 2.3. Been working with this app for 4 years but now that im having more opened accounts Im having this problem. Please Im desperate! :-( Many thanks in advance!
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>
persistence.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>
I've found a way of making it work. I don't know exactly which line is making it work or if it is the whole:
This code it seems it works. I dont know if what it makes it work is closing and opening PM for every account, or getting KEYS and then obtaining each account by its KEY or flushing before closing PM. Since I only can reproduce this error in PRODUCTION I cannot test what makes it work and what is not necessary. I know this code works.