针对mysqli_commit故障会自动回滚吗?和mysql故障处理这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展MySQLmysqli_connect()不能连接数据库问题、mysqls
针对mysqli_commit故障会自动回滚吗?和mysql故障处理这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展MySQL mysqli_connect() 不能连接数据库问题、mysql select 需要提交 commit 吗?、mysql _提交 commit 与 事务回滚roll back()、MySQL 事务 autocommit 自动提交等相关知识,希望可以帮助到你。
本文目录一览:- mysqli_commit故障会自动回滚吗?(mysql故障处理)
- MySQL mysqli_connect() 不能连接数据库问题
- mysql select 需要提交 commit 吗?
- mysql _提交 commit 与 事务回滚roll back()
- MySQL 事务 autocommit 自动提交
mysqli_commit故障会自动回滚吗?(mysql故障处理)
我对PHP手册中的代码如何运行有一些疑问.我看到了其他引发异常(通常是面向对象的代码)或使用标志来跟踪每个查询失败的示例.
我的问题是,为什么在决定提交或回滚之前,您必须标记错误并测试该标记.查看下面的示例,看来如果提交不起作用,则无论如何都不会提交任何查询.
我还注意到它们只是在提交失败时退出.这会自动回滚所有内容吗?
<?PHP
$link = MysqLi_connect("localhost", "my_user", "my_password", "test");
/* check connection */
if (!$link) {
printf("Connect Failed: %s\n", MysqLi_connect_error());
exit();
}
/* set autocommit to off */
MysqLi_autocommit($link, FALSE);
MysqLi_query($link, "CREATE TABLE Language LIKE CountryLanguage");
/* Insert some values */
MysqLi_query($link, "INSERT INTO Language VALUES ('DEU', 'Bavarian', 'F', 11.2)");
MysqLi_query($link, "INSERT INTO Language VALUES ('DEU', 'Swabian', 'F', 9.4)");
/* commit transaction */
if (!MysqLi_commit($link)) {
print("Transaction commit Failed\n");
exit();
}
/* close connection */
MysqLi_close($link);
?>
解决方法:
Looking at the example below it appears that if the commit does not work, none of the queries would be committed anyway.
对.
但要点是,不仅提交会发生错误.但是-更有可能-执行其中一个查询.因此,您不仅需要检查提交结果,还需要检查每个查询的结果并中止整个操作.
因此,您的问题应读为
Does a MysqLi failure automatically rollback?
答案是“是,不是”.
默认情况下不会.
但是,如果您因查询失败而中止脚本,则链接将关闭,并且事务将自动回滚.下面的代码将MysqL错误转换为PHP致命错误,如果其中一个查询失败,它将自动回滚.
<?PHP
/* set the proper error reporting mode */
MysqLi_report(MysqLI_REPORT_ERROR | MysqLI_REPORT_STRICT);
$link = MysqLi_connect("localhost", "my_user", "my_password", "test");
/* set autocommit to off */
MysqLi_autocommit($link, FALSE);
/* Run your queries */
MysqLi_query($link, "CREATE TABLE Language LIKE CountryLanguage");
MysqLi_query($link, "INSERT INTO Language VALUES ('DEU', 'Bavarian', 'F', 11.2)");
MysqLi_query($link, "INSERT INTO Language VALUES ('DEU', 'Swabian', 'F', 9.4)");
/* commit transaction */
MysqLi_commit($link);
/* this is the last line, NO other code is needed */
MySQL mysqli_connect() 不能连接数据库问题
事情是这样的。 这样的代码能行:
$servername = "localhost";
$username = "username";
$password = "password";
// 创建连接
$conn = new mysqli($servername, $username, $password);
// 检测连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
echo "连接成功";
这样的代码能行:
$servername = "localhost";
$username = "username";
$password = "password";
$link = mysqli_connect($servername, $username, $password, ''wxjs'');
if (!$link) {
echo "Error: Unable to connect to MySQL." . PHP_EOL;
echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
exit;
}
echo "Success: A proper connection to MySQL was made! The my_db database is great." . PHP_EOL;
echo "Host information: " . mysqli_get_host_info($link) . PHP_EOL;
mysqli_close($link);
输出:
Success: A proper connection to MySQL was made! The my_db database is great.
Host information: Localhost via UNIX socket
这样的代码不行:
$servername = "127.0.0.1";
$username = "username";
$password = "password";
$link = mysqli_connect($servername, $username, $password, ''wxjs'');
if (!$link) {
echo "Error: Unable to connect to MySQL." . PHP_EOL;
echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
exit;
}
echo "Success: A proper connection to MySQL was made! The my_db database is great." . PHP_EOL;
echo "Host information: " . mysqli_get_host_info($link) . PHP_EOL;
mysqli_close($link);
输出:
Error: Unable to connect to MySQL.
Debugging errno: 2002
Debugging error: Permission denied
得出结论:用IP和用localhost是不一样的。
我还找到了一个很变态的方法解决 用 IP 不行的,居然是关掉防火墙……
$ sudo setenforce 0
MySQL 新手。幼稚了……
mysql select 需要提交 commit 吗?
看你的需求!
mysql 的 innodb 支持多种事务隔离级别:
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
默认的隔离级别是 REPEATABLE READ
pgsql 的默认的隔离级别是READ COMMITTED
;sql server 默认是READ UNCOMMITTED
; oracle 默认是Read Committed
我们使用 mysql 的默认事务隔离级别,又关闭了自动提交事务:SET AUTOCOMMIT = 0
。又恰巧,你使用 select 后不使用 commit。那你这辈子会只能读取到重复的数据。
比如下面一个表:
连接 1 ,读取 id = 1 的 row
连接 2,修改 id=1 的 row 的 name 为 pon
这个时候,连接 1 再读取 id=1 的 row,你觉得 name 是什么?是 1 还是 pon?
答案是 1 ,而不是 pon
这很可怕
那要怎么才能读取到 pon 而不是 1 呢?
- 方案一:对于连接 1,select 之后,指定 commit、roollback、begin 等等操作,来新开一个事务
- 方案二:调整事务隔离级别为
READ COMMITTED
import pymysql
import pymysql.cursors
from pymysql.connections import Connection
from loguru import logger
# Connect to the database
connection_1: Connection = pymysql.connect(host=''192.168.31.245'',
user=''root'',
password=''xxxx'',
port=3306,
database=''seckill'',
cursorclass=pymysql.cursors.DictCursor)
cursor_1 = connection_1.cursor()
connection_2: Connection = pymysql.connect(host=''192.168.31.245'',
user=''root'',
password=''xxxx'',
port=3306,
database=''seckill'',
cursorclass=pymysql.cursors.DictCursor)
cursor_2 = connection_2.cursor()
sql = """
SELECT * FROM account WHERE id=1;
""".strip()
cursor_1.execute(sql)
logger.debug(cursor_1.fetchall())
connection_1.commit()
# sql = """
# DELETE FROM account where name=''jike'';
# """.strip()
sql = """
UPDATE account SET name="pon" WHERE id=1;
""".strip()
cursor_2.execute(sql)
connection_2.commit()
sql = """
SELECT * FROM account WHERE id=1;
""".strip()
cursor_1.execute(sql)
logger.debug(cursor_1.fetchall())
调整事务隔离级别,有 SESSION 和 GLOBAL 两种作用域
SET {SESSION | GLOBAL} TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE};
参考:开发中经常需要确认mysql的一些信息
mysql _提交 commit 与 事务回滚roll back()
1,进行插入之后,再提交,数据库有数据
2,进行插入之后,进行事务回滚,相当于撤消当前插入动作(相当于清空此次插入数据)
1 //创建表:
2 CREATE TABLE `test_tab` (
3 `f1` int(11) NOT NULL ,
4 `f2` varchar(11) DEFAULT NULL ,
5 PRIMARY KEY (`f1`)
6 )
7 ENGINE=InnoDB
[例子],插入数据进入test_tab表,字段[1]是不可重复键值
try:
INSERT INTO test_tab VALUES (1, ''2'');
print(1)
INSERT INTO test_tab VALUES (1, ''3'');
print(2)
commit()
excet ....:
roll back()
输出结果
>>>1
>>>[Err] 1062 - Duplicate entry ''1'' for key ''PRIMARY''
可以看出,第一条是可以插入的,但是第二条出现错误,commit没有提交,跳转至roll back()之后,第一条也撤消,所以没有数据插入
[例子2]
如果只是单纯的插入
1 INSERT INTO test_tab VALUES (1, ''2'');
如上,说明已经开启了一个事务,并且已经执行了一条正解的插入数据操作,虽然没有提交,但是之后有数据插入进行commit操作时,之前的插入数据将会一并显示在数据库内
如果之前数据插入时是成功的,其中有一条执行错误,那么使用roll back()事务回滚时,将会清空之前所插入而并未提交的数据
MySQL 事务 autocommit 自动提交
MySQL 默认操作模式就是 autocommit 自动提交模式。这就表示除非显式地开始一个事务,否则每个查询都被当做一个单独的事务自动执行。我们可以通过设置 autocommit 的值改变是否是自动提交 autocommit 模式。
通过以下命令可以查看当前 autocommit 模式
mysql> show variables like ''autocommit'';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.04 sec)
从查询结果中,我们发现 Value 的值是 ON,表示 autocommit 开启。我们可以通过以下 SQL 语句改变这个模式
1
mysql> set autocommit = 0;
值 0 和 OFF 都是一样的,当然,1 也就表示 ON。通过以上设置 autocommit=0,则用户将一直处于某个事务中,直到执行一条 commit 提交或 rollback 语句才会结束当前事务重新开始一个新的事务。
举个例子:
张三给李四转账 500 元。那么在数据库中应该是以下操作:
1,先查询张三的账户余额是否足够
2,张三的账户上减去 500 元
3,李四的账户上加上 500 元
以上三个步骤就可以放在一个事务中执行提交,要么全部执行要么全部不执行,如果一切都 OK 就 commit 提交永久性更改数据;如果出错则 rollback 回滚到更改前的状态。利用事务处理就不会出现张三的钱少了李四的账户却没有增加 500 元或者张三的钱没有减去李四的账户却加了 500 元。
MySQL 默认的存储引擎是 MyISAM,MyISAM 存储引擎不支持事务处理,所以改变 autocommit 没有什么作用。但不会报错,所以要使用事务处理的童鞋一定要确定你所操作的表示支持事务处理的,如 InnoDB。如果不知道表的存储引擎可以通过查看建表语句查看建表的时候有没有指定事务类型的存储引擎,如果没有指定存储引擎默认则是 MyISAM 不支持事务的存储引擎。
当然,事务处理是为了保障表数据原子性、一致性、隔离性、持久性。这些都是要消耗系统资源的,要谨慎选择。
今天关于mysqli_commit故障会自动回滚吗?和mysql故障处理的分享就到这里,希望大家有所收获,若想了解更多关于MySQL mysqli_connect() 不能连接数据库问题、mysql select 需要提交 commit 吗?、mysql _提交 commit 与 事务回滚roll back()、MySQL 事务 autocommit 自动提交等相关知识,可以在本站进行查询。
本文标签: