关于自治事务和锁PRAGMAAUTONOMOUS_TRANSACTION&LOCK
之前遇到的一个问题, 可以稳定重现. Oracle 的 INV 提供了一个接口 inv_lot_api_pub.auto_gen_lot() , 用来自动为 item 产生 lot number, 调用一次这个接口, lot number 就会自动 + 1; 看里头的代码, 是先从 MTL_SYSTEM_ITEMS 这个表里面取出一个字段 start_
之前遇到的一个问题, 可以稳定重现.
Oracle 的 INV 提供了一个接口 inv_lot_api_pub.auto_gen_lot() , 用来自动为 item 产生 lot number, 调用一次这个接口, lot number 就会自动 + 1; 看里头的代码, 是先从 MTL_SYSTEM_ITEMS 这个表里面取出一个字段 start_auto_lot_number, 比方说取出来的数值是1000, 那么就会把 1000 当做当前的 lot number, 接着会调用一个 procedure, 去更新这个字段, 变成 1001. 这个procedure 名字叫做 update_msi(). 最后去验证 1000 这个 lot number 是不是已经存在了. 如果存在, 那么会重新取出 1001 当做当前 lot number, 并且验证是不是存在, 直到找到没有重复的lot number, 就把它返回给调用 api 的地方.
那么这段代码会有什么问题呢? 我们假设一个场景, 有两个 session 同时调用这个 api, 那么在从 MSI 取数据的阶段, 有可能两个 session 会取出来相同的lot number. 嗯, 这个是有可能的. 如果这两个 session 是在为同一个 item 产生 lot number 就还好, 但是如果是不同的item, 就会为不同的两个 item 产生相同的 lot number. 这样数据就错了.
解决的办法就是通过锁来锁住被选择的 lot number, 并且在更新成功之后释放锁.
锁住选择的数据的方法是使用 for update 语句
SELECT auto_lot_alpha_prefix, start_auto_lot_number INTO l_lot_prefix, l_lot_suffix FROM mtl_system_items WHERE organization_id = p_org_id AND inventory_item_id = p_inventory_item_id for update
一旦有数据被选中, 那么同样使用这个 SQL 的session 将不能获得这些数据, 这就保证了无法产生相同的lot number. 当成功更新 lot number 之后, 就可以用 commit 释放锁了.
那么问题来了, 如果我们使用 commit 提交这个事务, 将会把所有的事务处理都提交, 那么如果之后出现错误回滚了, 将会有一部分数据提交, 另一部分数据回滚了. 解决的办法是使用自治事务. 从 select for update 语句开始, 到update MSI 并 commit 为止, 我们定义一个 procedure 并声明这是一个 PRAGMA AUTONOMOUS_TRANSACTION. 这样提交事务的时候就只会提交这个自治事务所做的更改, 并且释放锁给其他语句使用. 在自治事务之外的数据更新操作都不会受到影响.
这样通过锁和声明自治事务, 就可以保证不会在两个 session 里面获取到相同的 lot number 了;

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Lockwaittimeoutexceeded;tryrestartingtransaction - Comment résoudre l'erreur MySQL : délai d'attente de transaction Lorsque vous utilisez la base de données MySQL, vous pouvez parfois rencontrer une erreur courante : Lockwaittimeoutexceeded;tryrestartingtransaction. Cette erreur indique que le délai d'attente de transaction a expiré. Cette erreur se produit généralement lorsque

Traitement des transactions MySQL : la différence entre la soumission automatique et la soumission manuelle Dans la base de données MySQL, une transaction est un ensemble d'instructions SQL soit toutes les exécutions réussissent, soit toutes les exécutions échouent, garantissant la cohérence et l'intégrité des données. Dans MySQL, les transactions peuvent être divisées en soumission automatique et soumission manuelle. La différence réside dans le moment de la soumission de la transaction et dans l'étendue du contrôle sur la transaction. Ce qui suit présentera en détail la différence entre la soumission automatique et la soumission manuelle, et donnera des exemples de code spécifiques à illustrer. 1. Soumettre automatiquement dans MySQL, s'il n'est pas affiché

1. Introduction à PDO PDO est une bibliothèque d'extension de PHP, qui fournit une manière orientée objet d'exploiter la base de données. PDO prend en charge une variété de bases de données, notamment Mysql, postgresql, Oracle, SQLServer, etc. PDO permet aux développeurs d'utiliser une API unifiée pour exploiter différentes bases de données, ce qui permet aux développeurs de basculer facilement entre différentes bases de données. 2. PDO se connecte à la base de données Pour utiliser PDO pour vous connecter à la base de données, vous devez d'abord créer un objet PDO. Le constructeur de l'objet PDO reçoit trois paramètres : type de base de données, nom d'hôte, nom d'utilisateur de la base de données et mot de passe. Par exemple, le code suivant crée un objet qui se connecte à une base de données MySQL : $dsn="mysq

L'extension PHP Data Objects (PDO) fournit une interaction efficace et orientée objet avec les serveurs de bases de données. Ses capacités avancées de requête et de mise à jour permettent aux développeurs d'effectuer des opérations de base de données complexes, améliorant ainsi les performances et la maintenabilité du code. Cet article approfondira les fonctions avancées de requête et de mise à jour de PDO et vous guidera pour maîtriser ses puissantes fonctions. Requêtes avancées : utilisation d'espaces réservés et de paramètres liés Les espaces réservés et les paramètres liés sont des outils importants pour améliorer les performances et la sécurité des requêtes. Les espaces réservés utilisent des points d'interrogation (?) pour représenter les paramètres remplaçables dans la requête, tandis que les paramètres de liaison vous permettent de spécifier le type de données et la valeur de chaque paramètre. En utilisant ces méthodes, vous pouvez éviter les attaques par injection SQL et améliorer les performances car le moteur de base de données peut optimiser les requêtes à l'avance. //Utiliser l'espace réservé $stmt=$

Le principe et les scénarios d'application des transactions MySQL Dans le système de base de données, une transaction est un ensemble d'opérations SQL. Ces opérations sont soit toutes exécutées avec succès, soit toutes échouent et sont annulées. En tant que système de gestion de base de données relationnelle couramment utilisé, MySQL prend en charge les caractéristiques des transactions et peut garantir que les données de la base de données sont garanties en termes de cohérence, d'isolement, de durabilité et d'atomicité. Cet article commencera par les principes de base des transactions MySQL, présentera ses scénarios d'application et fournira des exemples de code spécifiques pour référence aux lecteurs. Le principe des transactions MySQL : Mon

Les transactions garantissent l'intégrité des données de la base de données, y compris l'atomicité, la cohérence, l'isolation et la durabilité. JDBC utilise l'interface Connection pour assurer le contrôle des transactions (setAutoCommit, commit, rollback). Les mécanismes de contrôle de concurrence coordonnent les opérations simultanées, à l'aide de verrous ou d'un contrôle de concurrence optimiste/pessimiste pour obtenir une isolation des transactions afin d'éviter les incohérences des données.

Méthodes de localisation et de réparation des erreurs de transaction PHP Au cours du processus de développement, nous impliquons souvent des opérations de base de données. Afin de garantir l'intégrité et la cohérence des données, lors du traitement des opérations de base de données, nous utilisons souvent des transactions pour garantir l'atomicité d'une série d'opérations. Cependant, dans le processus de développement réel, des erreurs se produisent parfois dans les transactions, entraînant des opérations de données incomplètes ou incohérentes. Cet article explique comment localiser et corriger les erreurs de transaction en PHP, tout en fournissant des exemples de code spécifiques. Pour localiser les erreurs de transaction en PHP, nous pouvons utiliser MySQLi ou

Quelles sont les techniques de traitement des transactions pour apprendre MySQL ? Introduction : La transaction est un concept très important dans le système de gestion de base de données. Elle fournit un mécanisme pour garantir l'intégrité et la cohérence des données. Dans MySQL, une transaction est l'unité d'exécution d'un ensemble d'instructions SQL, ce qui peut garantir que toutes les instructions SQL de cet ensemble d'instructions sont soit exécutées avec succès, soit annulées si toutes les exécutions échouent. Cet article présentera les compétences de traitement des transactions liées à l'apprentissage de MySQL et donnera des exemples de code correspondants. Démarrer une transaction : dans MySQL, vous pouvez utiliser BEGIN et STARTTRAN
