{"id":6164,"date":"2022-04-05T18:43:12","date_gmt":"2022-04-05T10:43:12","guid":{"rendered":"https:\/\/egonlin.com\/?p=6164"},"modified":"2022-04-16T19:38:29","modified_gmt":"2022-04-16T11:38:29","slug":"%e7%ac%ac%e5%8d%81%e4%b8%80%e8%8a%82%ef%bc%9adjango%e4%b8%adorm%e7%9a%84%e9%94%81","status":"publish","type":"post","link":"https:\/\/egonlin.com\/?p=6164","title":{"rendered":"\u7b2c\u5341\u4e00\u8282\uff1adjango\u4e2dORM\u7684\u9501"},"content":{"rendered":"<h1>django\u4e2dORM\u7684\u9501<\/h1>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/egonlin.com\/wp-content\/uploads\/2022\/04\/django\u4e2dORM\u7684\u95011.jpg'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  data-original=\"https:\/\/egonlin.com\/wp-content\/uploads\/2022\/04\/django\u4e2dORM\u7684\u95011.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" \/><\/div><\/p>\n<h2>\u4e00\u3001\u884c\u9501<\/h2>\n<pre><code class=\"language-python\">select_for_update(nowait=False, skip_locked=False)\n\u6ce8\u610f\u5fc5\u987b\u7528\u5728\u4e8b\u52a1\u91cc\u9762\uff0c\u81f3\u4e8e\u5982\u4f55\u5f00\u542f\u4e8b\u52a1\uff0c\u6211\u4eec\u770b\u4e0b\u9762\u7684\u4e8b\u52a1\u4e00\u8282 Book.objects.select_for_update().filter(nid=3)  # \u9501\u4f4fnid=3\u7684\u884c\n\n# \u6570\u636e\u5e93\u9501\u673a\u5236\u8be6\u89c1\nhttps:\/\/www.cnblogs.com\/linhaifeng\/articles\/14386584.html<\/code><\/pre>\n<p>select_for_update\u4e2d\u7684\u4e24\u4e2a\u53c2\u6570\u4e86\u89e3\u5373\u53ef\uff0c\u56e0\u4e3a\u5728MySQL\u4e2d\u538b\u6839\u4e0d\u652f\u6301\u5f00\u542f\u5b83\u4eec<\/p>\n<p>\u4e00\u822c\u60c5\u51b5\u4e0b\u5982\u679c\u5176\u4ed6\u4e8b\u52a1\u9501\u5b9a\u4e86\u76f8\u5173\u884c\uff0c\u90a3\u4e48\u672c\u67e5\u8be2\u5c06\u88ab\u963b\u585e\uff0c\u76f4\u5230\u9501\u88ab\u91ca\u653e\u3002 \u5982\u679c\u8fd9\u4e0d\u60f3\u8981\u4f7f\u67e5\u8be2\u963b\u585e \u7684\u8bdd\uff0c\u4f7f\u7528select_for_update(nowait=True)\u3002 \u5982\u679c\u5176\u5b83\u4e8b\u52a1\u6301\u6709\u51b2\u7a81\u7684\u9501\uff0c\u4e92\u65a5\u9501, \u90a3\u4e48\u67e5\u8be2\u5c06\u5f15\u53d1 DatabaseError \u5f02\u5e38\u3002\u4f60\u4e5f\u53ef\u4ee5\u4f7f\u7528select_for_update(skip_locked=True)\u5ffd\u7565\u9501\u5b9a\u7684\u884c\u3002 nowait\u548c\u3000\u3000skip_locked\u662f\u4e92\u65a5\u7684\uff0c\u540c\u65f6\u8bbe\u7f6e\u4f1a\u5bfc\u81f4ValueError\u3002*<br \/>\n*<em><br \/>\n<\/em>\u76ee\u524d\uff0cpostgresql\uff0coracle\u548cmysql\u6570\u636e\u5e93\u540e\u7aef\u652f\u6301select_for_update()\u3002 \u4f46\u662f\uff0cMySQL\u4e0d\u652f\u6301nowait\u548cskip_locked\u53c2\u6570\u3002<\/p>\n<h2>\u4e8c\u3001\u8868\u9501(\u4e86\u89e3)<\/h2>\n<pre><code class=\"language-python\">class LockingManager(models.Manager):\n    &quot;&quot;&quot; Add lock\/unlock functionality to manager.\n\n    Example::\n\n        class Job(models.Model): #\u5176\u5b9e\u4e0d\u7528\u8fd9\u4e48\u590d\u6742\uff0c\u76f4\u63a5\u5728orm\u521b\u5efa\u8868\u7684\u65f6\u5019\uff0c\u7ed9\u8fd9\u4e2a\u8868\u5b9a\u4e49\u4e00\u4e2alock\u548cunlock\u65b9\u6cd5\uff0c\n        # \u501f\u52a9django\u63d0\u4f9b\u7684connection\u6a21\u5757\u6765\u53d1\u9001\u9501\u8868\u7684\u539f\u751fsql\u8bed\u53e5\u548c\u89e3\u9501\u7684\u539f\u751fsql\u8bed\u53e5\u5c31\u53ef\u4ee5\u4e86\uff0c\n        # \u4e0d\u7528\u5916\u5c42\u7684\u8fd9\u4e2aLckingManager(model.Manager)\u7c7b\n\n            manager = LockingManager()\n\n            counter = models.IntegerField(null=True, default=0)\n\n            @staticmethod\n            def do_atomic_update(job_id)\n                &#039;&#039;&#039; Updates job integer, keeping it below 5 &#039;&#039;&#039;\n                try:\n                    # Ensure only one HTTP request can do this update at once.\n                    Job.objects.lock()\n\n                    job = Job.object.get(id=job_id)\n                    # If we don&#039;t lock the tables two simultanous\n                    # requests might both increase the counter\n                    # going over 5\n                    if job.counter &lt; 5:\n                        job.counter += 1                                        \n                        job.save()\n\n                finally:\n                    Job.objects.unlock()\n\n    &quot;&quot;&quot;    \n\n    def lock(self):\n        &quot;&quot;&quot; Lock table. \n\n        Locks the object model table so that atomic update is possible.\n        Simulatenous database access request pend until the lock is unlock()&#039;ed.\n\n        Note: If you need to lock multiple tables, you need to do lock them\n        all in one SQL clause and this function is not enough. To avoid\n        dead lock, all tables must be locked in the same order.\n\n        See http:\/\/dev.mysql.com\/doc\/refman\/5.0\/en\/lock-tables.html\n        &quot;&quot;&quot;\n        cursor = connection.cursor()\n        table = self.model._meta.db_table\n        logger.debug(&quot;Locking table %s&quot; % table)\n        cursor.execute(&quot;LOCK TABLES %s WRITE&quot; % table)\n        row = cursor.fetchone()\n        return row\n\n    def unlock(self):\n        &quot;&quot;&quot; Unlock the table. &quot;&quot;&quot;\n        cursor = connection.cursor()\n        table = self.model._meta.db_table\n        cursor.execute(&quot;UNLOCK TABLES&quot;)\n        row = cursor.fetchone()\n        return row <\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>django\u4e2dORM\u7684\u9501 \u4e00\u3001\u884c\u9501 select_for_update(nowait=False, skip_ [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":6778,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,405],"tags":[],"_links":{"self":[{"href":"https:\/\/egonlin.com\/index.php?rest_route=\/wp\/v2\/posts\/6164"}],"collection":[{"href":"https:\/\/egonlin.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/egonlin.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/egonlin.com\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/egonlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6164"}],"version-history":[{"count":0,"href":"https:\/\/egonlin.com\/index.php?rest_route=\/wp\/v2\/posts\/6164\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/egonlin.com\/index.php?rest_route=\/wp\/v2\/media\/6778"}],"wp:attachment":[{"href":"https:\/\/egonlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6164"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/egonlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6164"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/egonlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6164"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}