在MySQL中获取未提交的数据

时间:2015-11-25 21:15:22

标签: php mysql codeigniter sql-server-2012 codeigniter-3

SQL Server中,我们可以在SQL Queries下面写一下,以便在数据库中获取未提交的数据。这意味着仍在交易和交易中的数据不完整。

SQL Server查询

Select * from TableName With(NoLock);

即使表被锁定,MySQL数据库中是否存在获取数据的等价物?我在PHP CodeIgnitor中尝试这个

5 个答案:

答案 0 :(得分:12)

找到一篇标题为" MySQL NOLOCK语法"

的文章

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代码使用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();

答案 1 :(得分:4)

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

<强> Reference

答案 2 :(得分:1)

只有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

代替。

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

答案 3 :(得分:1)

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语句。看到 Section 13.3.1, “START TRANSACTION, COMMIT, and ROLLBACK Syntax”

默认情况下,客户端连接以autocommit设置为1开始。要使客户端以默认值0开始,请通过使用--autocommit = 0选项启动服务器来设置全局自动提交值。要使用选项文件设置变量,请包含以下行:

[mysqld]
autocommit=0

See This also

答案 4 :(得分:1)

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

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

您可以获得有关MySQL isolation level in the documentation的更多信息。这需要innoDB表。

有关simple_query()的详细信息,根据codeigniter documentation,在查询未返回任何结果时使用它。