web-dev-qa-db-ja.com

MySQLでコミットされていないデータを取得する

SQL Server以下に書きますSQL Queriesデータベース内のコミットされていないデータを取得します。これは、トランザクション中であり、トランザクションが完了していないデータを意味します。

SQL Serverクエリ

Select * from TableName With(NoLock);

テーブルがロックされている場合でも、MySQLデータベースに同等のものはありませんか?PHP CodeIgnitorでこれを試しています

19
user5600983

MySQL NOLOCK syntax」というタイトルの記事が見つかりました

http://itecsoftware.com/with-nolock-table-hint-equivalent-for-mysql

SQL Server WITH(NOLOCK)は次のようになります。

SELECT * FROM TABLE_NAME WITH (nolock)

MySQLで同じことを実現するには、SET SESSIONコマンドを使用してセッション分離モードを変更します。

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
 SELECT * FROM TABLE_NAME ;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;

以下でも同じことを達成できます:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
COMMIT ;

このステートメントは、WITH(NOLOCK)、つまりREAD UNCOMMITTEDデータと同様に機能します。すべての接続の分離レベルをグローバルに設定することもできます。

 SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;

さらに、MySQLサーバーには、分離レベルに関連する2つのシステム変数も存在します。

SELECT @@global.tx_isolation; (global isolation level)
SELECT @@tx_isolation; (session isolation level)

または、トランザクション内に分離レベルを設定します。

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO

コードイグナイターでは、最初の2つのソリューションでクエリをラップするか、グローバルオプションを使用できます。

参考のために、以下のコードを使用できます。

$this->db->query("SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE");
$this->db->trans_start();

// your code

$this->db->trans_complete();

更新1:

ステートメントを実行する前に、クエリに分離レベルを設定するだけです。以下は、単純なphp mysqliコードtuを使用したものですisolation level read uncommited

//db connection
$mysqli = new mysqli('localhost', 'user', 'pass', 'db');

//set isolation level
$mysqli->query("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");

//your Select Query
$results = $mysqli->query("SELECT * FROM tablename");


while($row = $results->fetch_assoc()) {
    //some statements
}

// Frees the memory associated with a result
$results->free();
$mysqli->query("COMMIT");
// close connection
$mysqli->close();
12
Chetan Ameta
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
COMMIT ;

参照

4
Pankaj

コードイグナイター内では、リクエストの前に次のコマンドを使用できます。

_$this->db->simple_query("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
_

ドキュメントのMySQL分離レベル に関する詳細情報を取得できます。これにはinnoDBテーブルが必要です。

codeigniter documentation によると、simple_query()の詳細については、クエリが結果を返さない場合に使用されます。

1
Adam

SELECTステートメントは非ロック方式で実行されますが、以前のバージョンの行が使用されている可能性があります。したがって、この分離レベルを使用すると、そのような読み取りは一貫しなくなります。これはダーティリードとも呼ばれます。それ以外の場合、この分離レベルはREAD COMMITTEDのように機能します。

シリアライズ可能

このレベルはREPEATABLE READに似ていますが、自動コミットが無効になっている場合、InnoDBはすべてのプレーンSELECTステートメントを暗黙的にSELECT ... LOCK IN SHARE MODEに変換します。自動コミットが有効な場合、SELECTは独自のトランザクションです。したがって、読み取り専用であることが知られており、一貫した(非ロック)読み取りとして実行され、他のトランザクションをブロックする必要がない場合は、シリアル化できます。 (他のトランザクションが選択された行を変更した場合にプレーンSELECTを強制的にブロックするには、自動コミットを無効にします。)

自動コミット

Command-Line Format --autocommit[=#]
System Variable Name    autocommit
Variable Scope  Global, Session
Dynamic Variable    Yes
Permitted Values    Type    boolean
Default ON

自動コミットモード。 1に設定すると、テーブルへのすべての変更がすぐに有効になります。 0に設定した場合は、COMMITを使用してトランザクションを受け入れるか、ROLLBACKを使用してトランザクションをキャンセルする必要があります。 autocommitが0で、1に変更すると、MySQLは開いているトランザクションの自動COMMITを実行します。トランザクションを開始する別の方法は、START TRANSACTIONまたはBEGINステートメントを使用することです。 セクション13.3.1、「START TRANSACTION、COMMIT、およびROLLBACK構文」 を参照してください。

デフォルトでは、クライアント接続はautocommitを1に設定して開始します。クライアントをデフォルトの0で開始するには、-autocommit = 0オプションを指定してサーバーを起動し、グローバル自動コミット値を設定します。オプションファイルを使用して変数を設定するには、次の行を含めます。

[mysqld]
autocommit=0

こちらもご覧ください

1
Alaa M. Jaddou

InnoDBストレージエンジンのみがトランザクションを完全にサポートします。また、暗黙的な行ロックが読み取りをブロックしないようにするOracle/PostgreSQLスタイルのMVCCも実装しています。 InnoDBでRead-Uncommittedを取得するには、クエリを発行する前にSET TRANSACTION LEVEL READ UNCOMMITTEDを発行します。

PHPでこれを行うための構文は、次のようになります。

$dbh->exec('SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED');
$dbh->beginTransaction();

これにより、次のCOMMITまたはROLLBACKまで分離レベルが設定されます。レベルの変更をセッション中に持続させるには、次を使用します。

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

代わりに。

テーブルまたは行の非共有読み取りロックをオーバーライドすることについては、それが可能かどうか確信が持てません。非共有ロックは通常、理由により非共有です。

1