概念回忆数据库事务
本文内容 事务 ACID 特征 并发调度——隔离级别 加锁机制 加锁协议 数据库事务,简称事务,是一组按顺序执行的操作单元。 事务 ACID 特征 事务有四个特征,称为 ACID: 原子性(Atomic)- 事务必须同时成功或同时失败。 比如,ATM 取钱和记入客户账户是一个
本文内容
- 事务 ACID 特征
- 并发调度——隔离级别
- 加锁机制
- 加锁协议
数据库事务,简称事务,是一组按顺序执行的操作单元。
事务 ACID 特征
事务有四个特征,称为 ACID:
- 原子性(Atomic)- 事务必须同时成功或同时失败。
比如,ATM 取钱和记入客户账户是一个原子事务。如果 ATM 只是吐出钱,而未记入账户,或是已记入账户,但没有吐出钱。这两种情况都是不允许的。
- 一致性(Consistency)- 事务必须遵循某个规则或法律协议系统。简单说,就是符合我们的所有期望。
事务必须以一种遵循系统规则的方式,成功地选择、插入、更新或删除记录。不遵循规则的事务,不能提交。如果没有绝对的规则,则持久性(数据完整性)将没有保证。比如,航班数据库,一个座位不能分配给两名不同的乘客。这就是一个一致性。在事务处理过程中的某个时刻,乘客之间可能需要调换座位,这可能会违背这个约束。但事务结束后,事务必须保证数据库满足所有的一致性条件。
- 隔离性(Isolation)- 用户不能看到其他用户的事务,直到那些事务全部完成并提交。
事务并发时,一个事务不应影响其他事务。事务之间是隔离的。比如,两个机票售票口,正在出售同一个航班的座位,而该航班只剩下一个座位,那么,只能满足一个售票口的请求,而拒绝另一个。如果由于并发操作而导致同一个座位卖给了两位乘客,或是没卖出去,都是不允许的。
- 持久性(Durability)- 事务必须持久有效。
事务一旦被提交,即使系统出现故障,也要保证事务的结果不能丢失。许多灾难性条件可能导致记录无法永久性保存到磁盘,包括电源、网络、系统和硬盘等设备的失败。数据丢失还可能由于心怀不满的员工或黑客的恶意操作引起。
但是,持久性不是自动化过程。DBA的主要职责之一就是创建并维护数据恢复策略。
James Nicholas Gray、Theo Haerder 和 Andreas Reuter 这三人为术语“数据库 ACID 测试”做出了很大贡献。
- James Nicholas Gray。他早在 1981 年,就为 Tandem Computers, Inc. 公司编写了白皮书 "The Transaction Concept: Virtues and Limitations"。在这篇文章中,Gray 认为事务应该是合法的、绑定的,并且必须具备如下特征:一致性、原子性、持久性。最后,他大致定义了提交(commit)、回滚(rollback)、取消(undo)和重做(redo)日志文件。这篇文章在当时很有前瞻性的,对现代数据库系统的影响非常显著。
- Theo Haerder 和 Andreas Reuter 为美国计算机协会(Association for Computing Machinery,ACM)写了一篇后续文章,题为 "Principles of Transaction-Oriented Database Recovery"。在这篇文章中,他们进一步扩展了 Gray的思想,增加了“事务必须相互隔离”的思想。新的事物特性如下:原子性、一致性、隔离性、持久性。
并发调度——隔离级别
如果对并发操作不进行合理调度,那么,会破坏事务 ACID 特性。可能会带来如下问题:
- 影子读取(丢失修改):一个事务读取了另一个事务已提交的数据。
例如,假设,两个事务 T1 和 T2:
事务 T1 和 T2 都从数据库读入同一记录,并各自修改数据,在两个事务都完成了读入数据的操作以后,T1 先完成修改操作,并将更新的数据写回数据库。
随后,T2 也完成了修改,并将结果写回数据库,这样就覆盖了 T1 的操作结果,导致 T1 对该数据的修改好像从未发生过。
这种情形称为“丢失修改”。
- 脏读取(dirty read):一个事务读取了未提交的事务。
例如,假设,两个事务 T1 和 T2:
事务 T1 修改了某个数据,并将其写回数据库。事务 T2 随之读入这个被 T1 修改过的数据,之后 T1 出于某种原因又撤销了,它所修改的数据被恢复。
这时,T2 所读取的数据就与数据库中的数据不同。
这种情形称为“脏读取”。
- 不可重复读取(non-repeatable read):一个事务多次读取同一个数据的返回结果不同。
例如,假设,两个事务 T1 和 T2:
事务 T1 按一定条件从数据库读取某些数据。随后,事务 T2 对其进行修改,并将其结果写回数据库。当 T1 再次按同一条件读取数据时,结果发现已经跟刚才不一样了。有些可能发生改变,有些可能已经删除,还可能增加了某些数据。
这种情况称为“不可重复读取”。
为了解决事务之间并发带来的问题,必须在事务之间建立隔离关系。如果应用程序使用完全隔离的事务,那么,同时执行多个事务的效果将完全等效于串行(一个接一个地)执行。隔离级别如下表所示。
隔离级别 | 脏读 | 不可重复读取 | 影子读取 | 描述 |
可序列化 (SERIALIZABLE) | 不可能 | 不可能 | 不可能 | 最严格的级别。事务串行执行,资源消耗最大 |
可重复读取 (REPEATABLE READ) | 不可能 | 不可能 | 可能 | 读取数据的事务允许其他事务继续访问该行数据,但未提交的写事务将会禁止其他事务访问该行。避免“脏读取”和“不可重复读取”,只是带来更多的性能损失 |
未提交读取 (READ UNCOMMITED) | 不可能 | 可能 | 可能 | 最低的事务隔离级别,保证读取过程中不会读取到非法数据
|
提交读取 (READ COMMITTED)
| 可能 | 可能 | 可能 | 大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统 |
加锁机制
数据库采用锁机制来实现事务隔离。
- 共享锁(share lock,S 锁,读锁):共享锁用于读取数据操作,它允许其他事务同时读取某锁定的资源,但不允许其他事务更新它——可以读,但不能改。
例如,事务 T 对数据 A 加了 S 锁,则 T 就可以对 A 进行读取,但不能修改;在 T 释放 A 上的 S 锁前,其他事务可以再对 A 加 S 锁,但不能加 X 锁,这样,可以读取 A,但不能修改 A。
- 排他锁(exclusive lock,X 锁,写锁):排它锁用于修改数据的场合。它锁定的资源,其他事务不能读取也不能修改——读都不让,更不用说改。
例如,若事务 T 对数据 A 加了 X 锁,则 T 就可以对 A 进行读取,以及修改 A;在 T 释放 A 上的 X 锁前,任何事务都不能对 A 加任何类型的锁,这样也就不能读取和修改 A。
加锁协议
为了保证并发控制的正确性,在使用加锁机制时,必须遵循一定原则,如何时申请 X 锁或 S 锁,何时释放锁等。不同的加锁协议(locking protocol)约定不同——保证数据一致性的三级锁协议和保证并行调度的两段锁(two-phase locking)协议,为并发提供不同程度的保证。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Go 言語は、効率的かつ簡潔で習得が容易なプログラミング言語であり、同時プログラミングやネットワーク プログラミングに優れているため、開発者に好まれています。実際の開発ではデータベースの操作が欠かせませんが、今回はGo言語を使ってデータベースの追加・削除・変更・クエリ操作を実装する方法を紹介します。 Go 言語では、データベースを操作するために通常、よく使用される SQL パッケージや gorm などのサードパーティ ライブラリを使用します。ここでは SQL パッケージを例として、データベースの追加、削除、変更、クエリ操作を実装する方法を紹介します。 MySQL データベースを使用していると仮定します。

Hibernate ポリモーフィック マッピングは、継承されたクラスをデータベースにマップでき、次のマッピング タイプを提供します。 join-subclass: 親クラスのすべての列を含む、サブクラス用の別個のテーブルを作成します。 table-per-class: サブクラス固有の列のみを含む、サブクラス用の別個のテーブルを作成します。 Union-subclass: join-subclass と似ていますが、親クラス テーブルがすべてのサブクラス列を結合します。

Apple の最新リリースの iOS18、iPadOS18、および macOS Sequoia システムでは、さまざまな理由で紛失または破損した写真やビデオをユーザーが簡単に回復できるように設計された重要な機能が写真アプリケーションに追加されました。この新機能では、写真アプリのツール セクションに「Recovered」というアルバムが導入され、ユーザーがデバイス上に写真ライブラリに含まれていない写真やビデオがある場合に自動的に表示されます。 「Recovered」アルバムの登場により、データベースの破損、カメラ アプリケーションが写真ライブラリに正しく保存されない、または写真ライブラリを管理するサードパーティ アプリケーションによって失われた写真やビデオに対する解決策が提供されます。ユーザーはいくつかの簡単な手順を実行するだけで済みます

HTML はデータベースを直接読み取ることはできませんが、JavaScript と AJAX を通じて実現できます。この手順には、データベース接続の確立、クエリの送信、応答の処理、ページの更新が含まれます。この記事では、JavaScript、AJAX、および PHP を使用して MySQL データベースからデータを読み取る実践的な例を示し、クエリ結果を HTML ページに動的に表示する方法を示します。この例では、XMLHttpRequest を使用してデータベース接続を確立し、クエリを送信して応答を処理することで、ページ要素にデータを埋め込み、データベースを読み取る HTML の機能を実現します。

MySQLi を使用して PHP でデータベース接続を確立する方法: MySQLi 拡張機能を含める (require_once) 接続関数を作成する (functionconnect_to_db) 接続関数を呼び出す ($conn=connect_to_db()) クエリを実行する ($result=$conn->query()) 閉じる接続 ( $conn->close())

PHP でデータベース接続エラーを処理するには、次の手順を使用できます。 mysqli_connect_errno() を使用してエラー コードを取得します。 mysqli_connect_error() を使用してエラー メッセージを取得します。これらのエラー メッセージをキャプチャしてログに記録することで、データベース接続の問題を簡単に特定して解決でき、アプリケーションをスムーズに実行できるようになります。

トランザクションは、原子性、一貫性、分離性、耐久性などのデータベース データの整合性を保証します。 JDBC は、Connection インターフェイスを使用してトランザクション制御 (setAutoCommit、コミット、ロールバック) を提供します。同時実行制御メカニズムは、ロックまたはオプティミスティック/ペシミスティック同時実行制御を使用して同時操作を調整し、トランザクションの分離を実現してデータの不整合を防ぎます。

Golang でデータベース コールバック関数を使用すると、次のことを実現できます。 指定されたデータベース操作が完了した後にカスタム コードを実行します。追加のコードを記述せずに、個別の関数を通じてカスタム動作を追加します。コールバック関数は、挿入、更新、削除、クエリ操作に使用できます。コールバック関数を使用するには、sql.Exec、sql.QueryRow、または sql.Query 関数を使用する必要があります。
