Have you tried querying and saving within the same transaction, instead of separately?
On Sep 2, 3:36 am, bcottam <[email protected]> wrote: > I'm trying to find out if I'm using the @Version annotation properly > in my project. > I read the "code snippets that work" from Max > Ross:http://gae-java-persistence.blogspot.com/2009/10/optimistic-locking-w... > ...but perhaps there's a subtle detail I'm missing. > > I have a class that gets frequent updates, and I query that class an > aweful lot (around 2-3 times per second, and yes: that is critical to > the application). > > The issue I'm seeing is that when I query this object for an update, I > often get an outdated version, even though I've got the @Version > annotation on the class level. > > I've not been able to duplicate the issue locally, however, I do see > it when I deploy my app. > I notice that the OPT_VERSION property in the datastore never seems to > change from "1". Also, I notice that (occasionally, but repeatably) > the value of the bean that I read (for update checking) is a few > versions behind what it should be. I can see this by executing a few > updates on a bean (sequentially, in different requests), and just > monitor the status of the bean (on 1 second intervals) in a different > browser. To see the status, I just have a GWT page that sends a > request every second asking for the status of a given bean. The issue > is visible via logging on the server side, so I know it's not just a > GWT async request getting lost and eventually finding it's way back to > me. > > Here is a simplified version of the class: > > @Version(strategy=VersionStrategy.VERSION_NUMBER) > @PersistenceCapable(identityType=IdentityType.APPLICATION) > public class Product extends BaseBean { > > �...@primarykey > �...@persistent(valueStrategy=IdGeneratorStrategy.IDENTITY) > Key id; > > �...@persistent > BigDecimal currentPrice; > > �...@persistent > Date bidStartDate; > > �...@persistent > Date bidEndDate; > > .... getters/setters > > } > > it's super class is BaseBean, it's just there to implement some > interfaces and provide a baseline equals implementation: > public abstract class BaseBean implements IsSerializable, > Serializable, Identifiable { > ... > public boolean equals(Object obj) {...} > .... > > } > > here is the method that I'm using to query/update the bean: > > public Product getUpdatedProduct(Key productId) { > return readObject(Product.class, productId); > > } > > public void placeBid(Key productId, BigDecimal bidAmount) { > //read object uses a dedicated PersistenceManager for reads > Product product = readObject(Product.class, productId); > BigDecimal oldPrice = product.getCurrentPrice(); > > // update the price > product.setCurrentPrice(oldPrice.add(bidAmount)); > > // saves use a fresh PersistenceManager, so you have to detach or > you'll get an exception > product = detatchCopy(product); > > saveObject(product); > > } > > public <T> T saveObject(T bean) { > PersistenceManager pm = PMF.get(); > Transaction tx = pm.currentTransaction(); > > try { > tx.begin(); > bean = pm.makePersistent(bean); > tx.commit(); > } > catch(Exception e) { > e.printStackTrace(); > } > finally { > wrapUpTransactionIfNeeded(pm, tx); > } > > return bean; > > } > > I'll be happy to provide more details if needed, I'm sure I'm missing > something silly, I just don't know what it is. > > Thanks in advance, > -bryce -- You received this message because you are subscribed to the Google Groups "Google App Engine for Java" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en.
