如何在 AppEngine (GAE) 中进行数据库锁定?

2024-05-10

在 GAE 中,我有一个充满“一次性”的表——诸如“最后使用的序列号”之类的东西,这些东西并不真正属于其他表。它是一个简单的字符串键和字符串值对。

我有一些代码来获取命名整数并递增它,如下所示:

@PersistenceCapable(detachable="true")
public class OneOff
{
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    @Persistent
    private String dataKey;

    @Persistent
    private String value;


    public OneOff(String kk, String vv)
    {
        this.dataKey = kk;
        this.value = vv;
    }


    public static OneOff persistOneOff(String kk, String vv)
    {
        OneOff oneoff= new OneOff(kk, vv);
        PersistenceManager pm = PMF.get().getPersistenceManager();
        try
        {
            pm.makePersistent(oneoff);
        }
        finally
        {
            pm.close();
        }

        return oneoff;
    }


    // snip...
    @SuppressWarnings("unchecked")
    synchronized
    public static int getIntValueForKeyAndIncrement(String kk, int deFltValue)
    {
        int result = 0;
        OneOff oneOff = null;

        PersistenceManager pm = PMF.get().getPersistenceManager();
        Query query = pm.newQuery(OneOff.class);
        query.setFilter("dataKey == kkParam");
        query.declareParameters("String kkParam");
        List<OneOff> oneOffs = (List<OneOff>) query.execute(kk);

        int count = oneOffs.size();
        if (count == 1)
        {
            oneOff = oneOffs.get(0);
            result = Integer.parseInt(oneOff.value);
        }
        else if (count == 0)
        {
            oneOff = new OneOff(kk, "default");
            result = deFltValue;
        }
        else
        {
                // Log WTF error.
        }

        // update object in DB.
        oneOff.value = "" + (result+1);
        try
        {
            pm.makePersistent(oneOff);
        }
        finally
        {
            pm.close();
        }

        return result;
    }
    // etc...

但是,当我拨打这些电话时:

int val1 = OneOff.getIntValueForKeyAndIncrement("someKey", 100);
int val2 = OneOff.getIntValueForKeyAndIncrement("someKey", 100);
int val3 = OneOff.getIntValueForKeyAndIncrement("someKey", 100);

有时我会得到所需的增量,有时我会得到相同的值。当我想锁定此特定事务的数据库时,我的数据库访问似乎正在异步运行。

我以为

    synchronized
    public static

应该为我这样做,但显然不是(可能是由于多个实例正在运行!)

无论如何——我怎样才能做我想做的事呢? (我想在获取和更新该值时锁定我的数据库,以使整个过程并发安全。)

Thanks!

==编辑==

我接受了罗伯特的正确答案,因为交易确实是我想要的。但是,为了完整起见,我在下面添加了更新的代码。我认为这是正确的,虽然我不确定if(oneOff==null)子句(try-catch 位。)

public static int getIntValueForKeyAndIncrement(String kk, int defltValue)
{
    int result = 0;
    Entity oneOff = null;
    int retries = 3;

    // Using Datastore Transactions
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    while (true)
    {
        com.google.appengine.api.datastore.Transaction txn = datastore.beginTransaction();
        try
        {
            Key oneOffKey = KeyFactory.createKey("OneOff", kk);
            oneOff = datastore.get (oneOffKey);
            result = Integer.parseInt((String) oneOff.getProperty("value"));
            oneOff.setProperty("value",  "" + (result+1));
            datastore.put(oneOff);
            txn.commit();
            break;
        }
        catch (EntityNotFoundException ex)
        {
            result = defltValue;
        }
        catch (ConcurrentModificationException ex)
        {
            if (--retries < 0)
            {
                throw ex;
            }
        }

        if (oneOff == null)
        {
            try
            {
                Key oneOffKey = KeyFactory.createKey("OneOff", kk);
                oneOff = new Entity(oneOffKey);
                oneOff.setProperty("value",  "" + (defltValue+1));
                datastore.put(txn, oneOff);
                datastore.put(oneOff);
                txn.commit();
                break;
            }
            finally
            {
                if (txn.isActive())
                {
                    txn.rollback();
                }
            }
        }
        else
        {
            if (txn.isActive())
            {
                txn.rollback();
            }
        }
    }
return result;
}

您应该在 a 中更新您的值交易 http://code.google.com/appengine/docs/java/datastore/transactions.html。只要您的读取和写入位于单个事务中,App Engine 的事务就会防止两个更新相互覆盖。一定要注意关于实体组的讨论。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 AppEngine (GAE) 中进行数据库锁定? 的相关文章

  • Google Cloud SDK 中对 google-auth 的依赖错误?

    我正在标准环境应用程序中使用谷歌云存储和谷歌云数据存储API 目前在本地 我尝试运行我的测试 使用 pytest 时有一种非常奇怪的行为 我发现 在测试期间 dev appserver fix sys path命令运行者pytest bed
  • 在 Java 中将日期从 UTC 转换为 PST

    我需要将日期从 Google App Engine 本地服务器时区转换为 Java 中的太平洋时间 我尝试使用 Calendar calstart Calendar getInstance calstart setTimeZone Time
  • 在 SQL Server 中获取帐户“锁定”状态

    我想解锁 SQL Server 中的一个帐户 在解锁之前 我必须检查该帐户是否被锁定 我只想在帐户被锁定时解锁 是否有任何 SQL 查询或存储过程来获取 SQL 用户的 锁定 状态 代表 Alex K 发布答案 SELECT LOGINPR
  • D 并发写入缓冲区

    假设您有一个大小为 N 的缓冲区 必须将其设置为确定的值 例如零或其他值 缓冲区中的此值设置分为 M 个线程 每个线程处理缓冲区的 N M 个元素 缓冲区不能immutable 因为我们改变了值 消息传递也不起作用 因为禁止传递 ref 或
  • 如何在多进程系统中实现锁定?

    我们正在并行运行许多詹金斯项目 我们使用 python 并且选择使用 pyenv 管理虚拟环境 不幸的是 pyenv 有一个众所周知的竞争条件 https github com yyuu pyenv issues 174 为了解决这个问题
  • 如何在C中同时运行两个子进程?

    所以我开始学习并发编程 但由于某种原因我什至无法掌握基础知识 我有一个名为 fork c 的文件 其中包含一个 main 方法 在此方法中 我将 main 分叉两次 分别进入子进程 1 和 2 在孩子 1 中 我打印了字符 A 50 次 在
  • Google App Engine CORS“解析 ./app.yaml 时出错:未知的 url 处理程序类型”

    我正在尝试将 CORS 应用到我的一个应用程序引擎 但遇到错误 我尝试查看其他答案 间距 的建议 但仍然错误 app yaml runtime nodejs10 env variables NODE ENV production CLOUD
  • 默认 GCS 存储桶名称

    根据https cloud google com appengine docs python googlecloudstorageclient activate https cloud google com appengine docs p
  • 执行 SELECT 或 INSERT

    我想写一些类似的东西CASE以我想要的方式在 PostgreSQL 中声明SELECT从表中 如果什么也没找到 我想INSERT改为放入表中 我的示例表allocated ideas看起来像这样 challenge id user id i
  • 什么是“非阻塞”并发?它与普通并发有何不同?

    什么是 非阻塞 并发 它与使用线程的普通并发有何不同 为什么不在所有需要并发的场景中都使用非阻塞并发呢 使用非阻塞并发有开销吗 我听说Java中可以实现非阻塞并发 我们是否应该在特定场景下使用此功能 将这些方法之一与集合一起使用是否有区别或
  • Python 多处理:全局对象未正确复制到子级

    前几天我回答了一个关于SO的问题 https stackoverflow com q 67047533 1925388关于并行读取 tar 文件 这是问题的要点 import bz2 import tarfile from multipro
  • 当一种语言是另一种语言的平行超集时,这意味着什么?

    我正在阅读关于实时并发 C 的期刊文章 http link springer com article 10 1007 2FBF00365999 并且它在摘要中提到 因此你们中的任何人都可以通过该链接查看上下文 Concurrent C 是
  • 如何在 devserver 上使用 Oauth 测试 Cloud Endpoints

    我的应用程序使用 Oauthed Cloud Endpoints 并且在生产中运行良好 我的问题是 在本地开发服务器上 我的 User 用户始终设置为 电子邮件受保护 cdn cgi l email protection 即使我已经完成了通
  • Google App Engine 的优点和缺点 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 2009 年 8 月 21 日更新列表 帮助我列出在 Google App Engine 上构建应用程序的所有优点和缺点 Pros 无需购买服务
  • 尽管我没有使用 AppEngine 或 Datastore,但我无法在项目上启用 firestore

    我正在尝试在一个项目上激活 firestore 但我没有使用 AppEngine 或 Datastore 并且出现此错误消息 无法为此项目启用 Firestore 目前无法在已使用 Cloud Datastore 或 App Engine
  • 如何从“gcloud”工具检索 App Engine 应用程序的源代码?

    我已迁移到新系统并丢失了 App Engine 应用程序的本地副本 愚蠢的是 我没有使用源代码管理 我知道我用过gcloud工具来检索我过去项目的源代码 但我似乎无法找到如何再次执行此操作 我发现的一切都指向如何使用appcfg py 其中
  • 无论线程如何,对象是否总是能看到其最新的内部状态?

    假设我有一个带有简单整数计数变量的可运行对象 每次可运行对象运行时该变量都会递增 该对象的一个 实例被提交以在计划的执行程序服务中定期运行 class Counter implements Runnable private int coun
  • Java 空值检查

    我有一个thread1 if object null object play 和另一个thread2可以写null into object随时参考 我将同时运行这些线程 我知道thread2可以重写object后参考null检查并会抛出Nu
  • Monitor.Pulse & Wait - 意外行为

    http www codeproject com Articles 28785 Thread synchronization Wait and Pulse demystified http www codeproject com Artic
  • 如何检测 Postgres 中持有锁的查询?

    我想不断跟踪 postgres 中的互锁 我碰到锁具监控 https wiki postgresql org wiki Lock Monitoring文章并尝试运行以下查询 SELECT bl pid AS blocked pid a us

随机推荐

  • 从源安全导出

    有没有办法从 Source Safe 导出文件 文件夹 即删除所有 scc 文件 就像 SVN 导出一样 只需进行常规获取 然后运行类似的操作 ATTRIB R scc S DEL F S Q scc 第一个命令从这些文件中删除只读标志 第
  • 使用 Python 抓取维基百科数据

    我正在尝试从以下内容中检索 3 列 NFL 球队 球员姓名 大学球队 维基百科页面 http en wikipedia org wiki 2008 NFL draft 我是 python 新手 一直在尝试使用 beautifulsoup 来
  • pandas 两个数据框交叉连接[重复]

    这个问题在这里已经有答案了 我找不到有关交叉联接的任何内容 包括合并 联接或其他一些内容 我需要使用 my function 作为 myfunc 处理两个数据帧 相当于 for itemA in df1 iterrows for itemB
  • 使用 Jasmine 模拟 jQuery ajax 调用

    我正在使用 Jasmine 2 5 2 为使用 jQuery 3 1 1 执行 Ajax 请求的代码编写单元测试 我想模拟 Ajax 调用 提供我自己的响应状态和文本 我正在使用 Jasmine ajax 插件 https github c
  • 如何从 silverlight 中的视图模型从一个视图导航到另一个视图?

    我有一个 ViewModel 和两个 View 如何从 ViewModel 导航到 View2 我在某处读到我们需要使用 PRISM 在 Silverlight 中从 ViewModel 打开多个视图 PRISM 有什么替代方案吗 理想情况
  • 访问特征矩阵的行向量时复制或引用

    我正在使用的代码Eigen http eigen tuxfamily org index php title Main Page矩阵库 我注意到在整个代码中 有如下访问器 RowVector3f V size t vertex index
  • 使用 C#.net 中的私有存储库的身份验证读取 BitBucket API

    我已经尝试了几天让 BitBucket API 为我工作 但是当涉及到让它为具有身份验证的私有存储库工作时 将问题设置为私有 当它们设置为公开 无需身份验证 一切正常 代码示例如下 static void Main string args
  • gcc 不太可能使用宏

    我正在编写一段关键代码 其逻辑大致如下 if expression is true do something with extremely low latency before the nuke blows up This branch i
  • 在python中调用subprocess.Popen时“系统找不到指定的文件”

    我正在尝试使用svnmerge py合并一些文件 它在底层使用 python 当我使用它时 我收到一个错误 系统找不到指定的文件 工作中的同事正在运行相同版本的svnmerge py 以及 python 2 5 2 特别是 r252 609
  • Caliburn micro 处于无应用程序对象模式,就像在 AutoCAD dll 插件中一样

    我正在使用 Caliburn Micro 开发 WPF 应用程序 该应用程序的一些视图需要加载到 AutoCAD 环境中 AutoCAD 编程环境允许开发 AutoCAD 插件 dll 类型 并将其加载到 AutoCAD 环境中 由于 Au
  • ajax 调用成功后点击链接 href

    我有一个正常的链接 a href http www google com class continue Continue a 我已将点击绑定到一个事件来发布 ajax 请求 如下所示 continue click function ajax
  • .Net Core appsettings.json 最佳实践 - 覆盖开发设置(或反之亦然)?

    寻找一种关于在 Net Core 中构造 appsettings json 文件的合理方法 是否应该将基本 appsettings json 文件配置为在开发环境中运行 然后基于环境的覆盖 例如 appsettings Production
  • 使用 cxf 插件将 grails 项目部署到 WAS 8 时遇到问题

    我对常规 Grails并尝试部署一个grails应用程序 WAR 文件 使用Grails 2 1 1 and CXF插件1 0 1 to WebSphere 8 这是我第一次部署Grails 2 1 1 app to WebSphere 8
  • 使用 WebSocket 是否会产生服务器成本?

    我已经离开了 PHP MySQL 的舒适区 因为语法 封装 过程的东西可能会让人沮丧 上周 我开始尝试并按照一些教程使用 Node js Socket IO 创建实时聊天应用程序 到目前为止 我从未使用过 WebSockets 做过任何事情
  • 函数“sum”的隐式声明在 C99 中无效

    我一直在寻找解决方案 但没有找到任何有帮助的东西 我收到以下错误 Implicit declaration of function sum is invalid in C99 Implicit declaration of function
  • 使用 Asp.Net 的 GCM 推送通知

    正如您可能已经看到的 Google 正在迁移其推送通知系统 http developer android com guide google gcm c2dm html http developer android com guide goo
  • 一起使用 Argparse 和 Json

    我是 Python 初学者 我想知道 Argparse 和 JSON 是否可以一起使用 说 我有变量p q r 我可以将它们添加到 argparse 中 parser add argument p param1 help x variabl
  • umbraco 适用于单声道吗?

    我想跑Umbraco http umbraco org 在单声道上 这可能吗 目前 Umbraco 无法在 Mono 上正常运行 但人们已经在努力实现这一目标 This http kevinfitzgerald net articles u
  • 即使获得平台签名也无法读取系统文件

    我已经构建了一个自定义 Android ROM 我已经使用平台签名签署了我的应用程序并添加了android sharedUserId android uid system 在清单文件中 我的应用程序被授予所有 签名 和 系统 级别权限 但不
  • 如何在 AppEngine (GAE) 中进行数据库锁定?

    在 GAE 中 我有一个充满 一次性 的表 诸如 最后使用的序列号 之类的东西 这些东西并不真正属于其他表 它是一个简单的字符串键和字符串值对 我有一些代码来获取命名整数并递增它 如下所示 PersistenceCapable detach