在SQL Server
中,我们可以在SQL Queries
下面写一下,以便在数据库中获取未提交的数据。这意味着仍在交易和交易中的数据不完整。
SQL Server查询
Select * from TableName With(NoLock);
即使表被锁定,MySQL数据库中是否存在获取数据的等价物?我在PHP CodeIgnitor中尝试这个
答案 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();
这会将隔离级别设置为下一个COMMIT
或ROLLBACK
。要在会话期间保持级别更改,请使用
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
答案 4 :(得分:1)
在代码点火器中,您可以在任何请求之前使用以下命令:
$this->db->simple_query("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
您可以获得有关MySQL isolation level in the documentation的更多信息。这需要innoDB表。
有关simple_query()
的详细信息,根据codeigniter documentation,在查询未返回任何结果时使用它。