搜索
首页数据库mysql教程mysql事务回滚使用与常见问题介绍

MYSQL中只有INNODB和BDB类型的数据表才能支持事务处理!其他的类型是不支持的!***:一般MYSQL数据库默认的引擎是MyISAM,这种引擎不支持事务!如果要让MYSQL支持事务,可以自己手动修改:

方法如下:

1.修改c:apervmysqlmy.ini文件,找到skip-InnoDB,在前面加上#,后保存文件。
2.在运行中输入:services.msc,重启mysql服务。
3.到中,mysql->show engines;(或执行mysql->show variables like 'have_%'; ),查看InnoDB为YES,即表示支持InnoDB了。
也就说明支持事务transaction了。
4.在创建表时,就可以为Storage Engine选择InnoDB引擎了。如果是以前创建的表,可以使用

 代码如下 复制代码
mysql->alter table table_name type=InnoDB;

mysql->alter table table_name engine=InnoDB;

来改变数据表的引擎以支持事务。


事务回滚在事务中,每个正确的原子操作都会被顺序执行,直到遇到错误的原子操作,此时事务会将之前的操作进行回滚。回滚的意思是如果之前是插入操作,那么会执行删除插入的记录,如果之前是update操作,也会执行update操作将之前的记录还原。因此,正确的原子操作是真正被执行过的。

MYSQL的事务处理主要有两种方法。
1、用begin,rollback,commit来实现
begin 开始一个事务
rollback 事务回滚
commit 事务确认
2、直接用set来改变mysql的自动提交模式
MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过
set autocommit=0 禁止自动提交
set autocommit=1 开启自动提交
来实现事务的处理。
当你用 set autocommit=0 的时候,你以后所有的SQL都将做为事务处理,直到你用commit确认或rollback结束。
注意当你结束这个事务的同时也开启了个新的事务!按第一种方法只将当前的作为一个事务!

PHP实现MySQL事务回滚

创建一个测试的:

 代码如下 复制代码

mysql> CREATE DATABASE `shop_test` DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
Query OK, 1 row affected (0.00 sec)

mysql> use shop_test;
Database changed

mysql> CREATE TABLE IF NOT EXISTS `user_account`(
    -> `user` varchar(20) NOT NULL,
    -> `money` INT(10) NOT NULL,
    -> PRIMARY KEY (`user`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
Query OK, 0 rows affected (0.51 sec)

mysql> CREATE TABLE IF NOT EXISTS `user_order`(
    -> `id` INT(10) NOT NULL,
    -> `user` VARCHAR(20) NOT NULL,
    -> `price` INT(10) NOT NULL,
    -> `count` INT(10) NOT NULL,
    -> PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci AUTO_INCREMENT=1;
Query OK, 0 rows affected (0.33 sec)

mysql> INSERT INTO `user_account` VALUES ('luchanghong', '100');
Query OK, 1 row affected (0.00 sec)
PHP测试代码:

$conn = mysql_connect('127.0.0.1', 'root', 'root');
mysql__db('shop_test');
mysql_query('SET NAMES UTF8');

# start transaction
mysql_query("START TRANSACTION");
$sql = "INSERT INTO `user_order` VALUES ('1', 'luchanghong', '10', '2')";
mysql_query($sql);
$sql_2 = "UPDATE `user_account` SET `money` = `money` - 10*2 WHERE `user` = 'luchanghong'";
mysql_query($sql_2);

if (mysql_errno()){
    echo "error";
    mysql_query("ROLLBACK");
}else{
    echo "OK";
    mysql_query("COMMIT");
}


执行一次后查看数据库:

 代码如下 复制代码

mysql> SELECT * FROM `user_account`;
+-------------+-------+
| user        | money |
+-------------+-------+
| luchanghong |    80 |
+-------------+-------+
1 row in set (0.00 sec)

mysql> SELECT * FROM `user_order`;
+----+-------------+-------+-------+
| id | user        | price | count |
+----+-------------+-------+-------+
|  1 | luchanghong |    10 |     2 |
+----+-------------+-------+-------+
1 row in set (0.00 sec)

那么,我添加一个条件,就是每次更新完 user_account 表后检查用户的 money 是否为负值,如果为负值那么就要撤销之前的操作,执行事务回滚。

 代码如下 复制代码

$conn = mysql_connect('127.0.0.1', 'root', 'root');
mysql_select_db('shop_test');
mysql_query('SET NAMES UTF8');

// start transaction
mysql_query("START TRANSACTION");
$sql = "INSERT INTO `user_order`(`user`, `price`, `count`) VALUES ('luchanghong', '10', '2')";
mysql_query($sql);
$sql_2 = "UPDATE `user_account` SET `money` = `money` - 10*2 WHERE `user` = 'luchanghong'";
mysql_query($sql_2);

if (mysql_errno()){
    echo "error n";
    mysql_query("ROLLBACK");
}else{
    $money = check_remain_money('luchanghong');
    echo $money." ";
    if ($money         echo "No enough money n";
        mysql_query("ROLLBACK");
    }else{
        echo "OK n";
        mysql_query("COMMIT");
    }  
}

function check_remain_money($user){
    $sql = "SELECT `money` FROM `user_account` WHERE `user` = '{$user}'";
    $result = mysql_fetch_assoc( mysql_query($sql) );
    return !empty($result) ? $result['money'] : 0;
}

接着,在shell下多次执行这php文件(WIN下就手动执行几次吧),例如:

 代码如下 复制代码

lch@LCH:~/Desktop $ for x in `seq 6`; do php transaction.php ; done
60 OK
40 OK
20 OK
0 OK
-20 No enough money
-20 No enough money
再看数据库数据:

mysql> SELECT * FROM `user_account`;
+-------------+-------+
| user        | money |
+-------------+-------+
| luchanghong |     0 |
+-------------+-------+
1 row in set (0.00 sec)

mysql> SELECT * FROM `user_order`;
+----+-------------+-------+-------+
| id | user        | price | count |
+----+-------------+-------+-------+
|  1 | luchanghong |    10 |     2 |
|  2 | luchanghong |    10 |     2 |
|  3 | luchanghong |    10 |     2 |
|  4 | luchanghong |    10 |     2 |
|  5 | luchanghong |    10 |     2 |
+----+-------------+-------+-------+
5 rows in set (0.00 sec)

1、为什么auto_increament没有回滚?
因为innodb的auto_increament的计数器记录的当前值是保存在存内 存中的,并不是存在于磁盘上,当mysql server处于运行的时候,这个计数值只会随着insert改增长,不会随着delete而减少。而当mysql server启动时,当我们需要去查询auto_increment计数值时,mysql便会自动执行:SELECT MAX(id) FROM 表名 FOR UPDATE;语句来获得当前auto_increment列的最大值,然后将这个值放到auto_increment计数器中。所以就算 Rollback MySQL的auto_increament计数器也不会作负运算。

2、MySQL的事务对表操作的时候是否是物理操作?
MySQL的事务是有redo和undo的,redo操作的所有信息都是记录到 redo_log中,也就是说当一个事务做commit操作时,需要先把这个事务的操作写到redo_log中,然后再把这些操作flush到磁盘上,当 出现故障时,只需要读取redo_log,然后再重新flush到磁盘就行了。
而对于undo就比较麻烦,MySQL在处理事务时,会在数据共享 表空间里申请一个段叫做segment段,用保存undo信息,当在处理rollback,不是完完全全的物理undo,而是逻辑undo,就是说会对之 前的操作进行反操作,但是这些共享表空间是不进行回收的。这些表空间的回收需要由mysql的master thread进程来进行回收。

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
在MySQL中使用视图的局限性是什么?在MySQL中使用视图的局限性是什么?May 14, 2025 am 12:10 AM

mysqlviewshavelimitations:1)他们不使用Supportallsqloperations,限制DatamanipulationThroughViewSwithJoinSorsubqueries.2)他们canimpactperformance,尤其是withcomplexcomplexclexeriesorlargedatasets.3)

确保您的MySQL数据库:添加用户并授予特权确保您的MySQL数据库:添加用户并授予特权May 14, 2025 am 12:09 AM

porthusermanagementInmysqliscialforenhancingsEcurityAndsingsmenting效率databaseoperation.1)usecReateusertoAddusers,指定connectionsourcewith@'localhost'or@'%'。

哪些因素会影响我可以在MySQL中使用的触发器数量?哪些因素会影响我可以在MySQL中使用的触发器数量?May 14, 2025 am 12:08 AM

mysqldoes notimposeahardlimitontriggers,butacticalfactorsdeterminetheireffactective:1)serverConfiguration impactactStriggerGermanagement; 2)复杂的TriggerSincreaseSySystemsystem load; 3)largertablesslowtriggerperfermance; 4)highConconcConcrencerCancancancancanceTigrignecentign; 5); 5)

mysql:存储斑点安全吗?mysql:存储斑点安全吗?May 14, 2025 am 12:07 AM

Yes,it'ssafetostoreBLOBdatainMySQL,butconsiderthesefactors:1)StorageSpace:BLOBscanconsumesignificantspace,potentiallyincreasingcostsandslowingperformance.2)Performance:LargerrowsizesduetoBLOBsmayslowdownqueries.3)BackupandRecovery:Theseprocessescanbe

mySQL:通过PHP Web界面添加用户mySQL:通过PHP Web界面添加用户May 14, 2025 am 12:04 AM

通过PHP网页界面添加MySQL用户可以使用MySQLi扩展。步骤如下:1.连接MySQL数据库,使用MySQLi扩展。2.创建用户,使用CREATEUSER语句,并使用PASSWORD()函数加密密码。3.防止SQL注入,使用mysqli_real_escape_string()函数处理用户输入。4.为新用户分配权限,使用GRANT语句。

mysql:blob和其他无-SQL存储,有什么区别?mysql:blob和其他无-SQL存储,有什么区别?May 13, 2025 am 12:14 AM

mysql'sblobissuitableForStoringBinaryDataWithInareLationalDatabase,而alenosqloptionslikemongodb,redis和calablesolutionsoluntionsoluntionsoluntionsolundortionsolunsolunsstructureddata.blobobobsimplobissimplobisslowderperformandperformanceperformancewithlararengelitiate;

mySQL添加用户:语法,选项和安全性最佳实践mySQL添加用户:语法,选项和安全性最佳实践May 13, 2025 am 12:12 AM

toaddauserinmysql,使用:createUser'username'@'host'Indessify'password'; there'showtodoitsecurely:1)choosethehostcarecarefullytocon trolaccess.2)setResourcelimitswithoptionslikemax_queries_per_hour.3)usestrong,iniquepasswords.4)Enforcessl/tlsconnectionswith

MySQL:如何避免字符串数据类型常见错误?MySQL:如何避免字符串数据类型常见错误?May 13, 2025 am 12:09 AM

toAvoidCommonMistakeswithStringDatatatPesInMysQl,CloseStringTypenuances,chosethirtightType,andManageEngencodingAndCollat​​ionsEttingsefectery.1)usecharforfixed lengengters lengengtings,varchar forbariaible lengength,varchariable length,andtext/blobforlabforlargerdata.2 seterters seterters seterters seterters

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境