繁体   English   中英

在MySQL中获取未提交的数据

[英]Get UnCommitted Data in MySQL

SQL Server我们可以在SQL Queries下面编写以获取数据库中的Un-Committed数据。 这意味着仍在交易和交易中的数据不完整。

SQL Server查询

Select * from TableName With(NoLock);

即使表被锁定,MySQL数据库中是否有任何等价来获取数据? 我在PHP CodeIgnitor中尝试这个

找到一篇标题为“ 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服务器中存在两个与隔离相关的系统变量:

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

或者在事务中设置隔离级别:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO

在代码点火器中,您可以使用前两个解决方案包装查询,也可以使用全局选项。

供您参考,您可以使用以下代码:

$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();
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
COMMIT ;

参考

只有InnoDB存储引擎完全支持事务。 它还实现了Oracle / PostgreSQL风格的MVCC,可防止隐式行锁阻塞读取。 要在InnoDB中获取Read-Uncommitted,请在发出查询之前发出SET TRANSACTION LEVEL READ UNCOMMITTED

在PHP中执行此操作的语法如下所示:

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

这将隔离级别设置为下一个COMMITROLLBACK 要在会话期间保持级别更改,请使用

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

代替。

至于覆盖表或行上的非共享读锁定,我不确定是否可行,也不能考虑可能需要的情况。 非共享锁通常是非共享的。

SELECT语句以非锁定方式执行,但可能使用行的早期版本。 因此,使用此隔离级别,此类读取不一致。 这也称为脏读。 否则,此隔离级别与READ COMMITTED类似。

SERIALIZABLE

这个级别就像REPEATABLE READ,但InnoDB隐式地将所有普通SELECT语句转换为SELECT ...如果禁用自动提交,则锁定共享模式。 如果启用了自动提交,则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

另见

在代码点火器中,您可以在任何请求之前使用以下命令:

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

您可以在文档中获得有关MySQL隔离级别的更多信息。 这需要innoDB表。

有关simple_query()更多信息,根据codeigniter文档 ,在查询未返回结果时使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM