mysql事务处理⽤法与实例详解
来源:转载
MySQL的事务⽀持不是绑定在MySQL服务器本⾝,⽽是与存储引擎相关1.MyISAM:不⽀持事务,⽤于只读程序提⾼性能 2.InnoDB:⽀持ACID事务、⾏级锁、并发 3.Berkeley DB:⽀持事务
⼀个事务是⼀个连续的⼀组操作,就好像它是⼀个单⼀的⼯作单元进⾏。换⾔之,永远不会是完整的事务,除⾮该组内的每个单独的操作是成功的。如果在事务的任何操作失败,则整个事务将失败。
实际上,会俱乐部许多SQL查询到⼀个组中,将执⾏所有的⼈都⼀起作为事务的⼀部分。
事务的特性:
事务有以下四个标准属性的缩写ACID,通常被称为:
原⼦性: 确保⼯作单元内的所有操作都成功完成,否则事务将被中⽌在故障点,和以前的操作将回滚到以前的状态。
⼀致性: 确保正确地改变状态后,成功提交的事务。
mysql面试题详解
隔离性: 使事务操作彼此独⽴的和透明的。
持久性: 确保提交的事务的结果或效果的系统出现故障的情况下仍然存在。
在MySQL中,事务开始使⽤COMMIT或ROLLBACK语句开始⼯作和结束。开始和结束语句的SQL命令之间形成了⼤量的事务。
COMMIT & ROLLBACK:
这两个关键字提交和回滚主要⽤于MySQL的事务。
当⼀个成功的事务完成后,发出COMMIT命令应使所有参与表的更改才会⽣效。
如果发⽣故障时,应发出⼀个ROLLBACK命令返回的事务中引⽤的每⼀个表到以前的状态。
可以控制的事务⾏为称为AUTOCOMMIT设置会话变量。如果AUTOCOMMIT设置为1(默认值),然后每⼀个SQL语句(在事务与否)被认为是⼀个完整的事务,并承诺在默认情况下,当它完成。 AUTOCOMMIT设置为0时,发出SET AUTOCOMMIT =0命令,在随后的⼀系列语句的作⽤就像⼀个事务,直到⼀个明确的COMMIT语句时,没有活动的提交。
可以通过使⽤mysql_query()函数在PHP中执⾏这些SQL命令。
通⽤事务例⼦
这⼀系列事件是独⽴于所使⽤的编程语⾔,可以建⽴在任何使⽤的语⾔来创建应⽤程序的逻辑路径。
可以通过使⽤mysql_query()函数在PHP中执⾏这些SQL命令。
BEGIN WORK开始事务发出SQL命令
发出⼀个或多个SQL命令,如SELECT,INSERT,UPDATE或DELETE
检查是否有任何错误,⼀切都依据的需要。
如果有任何错误,那么问题ROLLBACK命令,否则发出COMMIT命令。
在MySQL中的事务安全表类型:
如果打算使⽤MySQL事务编程,那么就需要⼀种特殊的⽅式创建表。有很多⽀持事务但最流⾏的是InnoDB表类型。
从源代码编译MySQL时,InnoDB表⽀持需要特定的编译参数。如果MySQL版本没有InnoDB⽀持,请互联⽹服务提供商建⽴⼀个版本的MySQL⽀持InnoDB表类型,或者下载并安装Windows或Linux/UNI
X的MySQL-Max⼆进制分发和使⽤的表类型在开发环境中。
如果MySQL安装⽀持InnoDB表,只需添加⼀个的TYPE=InnoDB 定义表创建语句。例如,下⾯的代码创建InnoDB表tcount_tbl:
代码如下复制代码
root@host# mysql -u root -p pass;
Enter password:*******
mysql> use TUTORIALS;
Database changed
mysql> create table tcount_tbl
-> (
-> tutorial_author varchar(40) NOT NULL,
-> tutorial_count INT
-> ) TYPE=InnoDB;
-> ) TYPE=InnoDB;
Query OK, 0 rows affected (0.05 sec)
可以使⽤其他GEMINI或BDB表类型,但它取决于您的安装,如果它⽀持这两种类型。
由于项⽬设计⾥⾯,牵扯到了⾦钱的转移,于是就要⽤到MYSQL的事务处理,来保证⼀组处理结果的正确性。⽤了事务,就不可避免的要牺牲⼀部分速度,来保证数据的正确性。
只有InnoDB⽀持事务
事务 ACID Atomicity(原⼦性)、Consistency(稳定性)、Isolation(隔离性)、Durability(可靠性)
1、事务的原⼦性
stripe和strip区别⼀组事务,要么成功;要么撤回。
2、稳定性
有⾮法数据(外键约束之类),事务撤回。
3、隔离性
事务独⽴运⾏。
⼀个事务处理后的结果,影响了其他事务,那么其他事务会撤回。
事务的100%隔离,需要牺牲速度。
4、可靠性
软、硬件崩溃后,InnoDB数据表驱动会利⽤⽇志⽂件重构修改。
可靠性和⾼速度不可兼得, innodb_flush_log_at_trx_commit选项决定什么时候吧事务保存到⽇志⾥。
开启事务
START TRANSACTION 或 BEGIN
提交事务(关闭事务)
COMMIT
放弃事务(关闭事务)
ROLLBACK
折返点
SAVEPOINT adqoo_1
ROLLBACK TO SAVEPOINT adqoo_1
发⽣在折返点 adqoo_1 之前的事务被提交,之后的被忽略
事务的终⽌
设置“⾃动提交”模式
ln函数图像SET AUTOCOMMIT = 0
每条SQL都是同⼀个事务的不同命令,之间由 COMMIT 或 ROLLBACK隔开
掉线后,没有 COMMIT 的事务都被放弃
事务锁定模式
系统默认:不需要等待某事务结束,可直接查询到结果,但不能再进⾏修改、删除。
缺点:查询到的结果,可能是已经过期的。
优点:不需要等待某事务结束,可直接查询到结果。
需要⽤以下模式来设定锁定模式
1、SELECT …… LOCK IN SHARE MODE(共享锁)
查询到的数据,就是数据库在这⼀时刻的数据(其他已commit事务的结果,已经反应到这⾥了)
SELECT 必须等待,某个事务结束后才能执⾏
2、SELECT …… FOR UPDATE(排它锁)
例如 SELECT * FROM tablename WHERE id<200
那么id<200的数据,被查询到的数据,都将不能再进⾏修改、删除、SELECT …… LOCK IN SHARE MODE操作
⼀直到此事务结束
共享锁和排它锁的区别:在于是否阻断其他客户发出的 SELECT …… LOCK IN SHARE MODE命令
3、INSERT / UPDATE / DELETE
所有关联数据都会被锁定,加上排它锁
4、防插⼊锁
例如 SELECT * FROM tablename WHERE id>200
那么id>200的记录⽆法被插⼊
5、死锁
⾃动识别死锁
先进来的进程被执⾏,后来的进程收到出错消息,并按ROLLBACK⽅式回滚
innodb_lock_wait_timeout = n 来设置最长等待时间,默认是50秒
事务隔离模式
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL
READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE
1、不带SESSION、GLOBAL的SET命令
只对下⼀个事务有效
2、SET SESSION
为当前会话设置隔离模式
3、SET GLOBAL
为以后新建的所有MYSQL连接设置隔离模式(当前连接不包括在内)
隔离模式
READ UNCOMMITTED
不隔离SELECT
其他事务未完成的修改(未COMMIT),其结果也考虑在内
READ COMMITTED
把其他事务的 COMMIT 修改考虑在内
同⼀个事务中,同⼀ SELECT 可能返回不同结果
REPEATABLE READ(默认)
不把其他事务的修改考虑在内,⽆论其他事务是否⽤COMMIT命令提交过
css鼠标点击改变样式同⼀个事务中,同⼀ SELECT 返回同⼀结果(前提是本事务,不修改)
SERIALIZABLE
和REPEATABLE READ类似,给所有的SELECT都加上了共享锁
出错处理
根据出错信息,执⾏相应的处理
mysql事物处理实例
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结束,注意当你结束这个事务的同时也开启了新的事务!按第⼀种⽅法只将当前的做为⼀个事务!
MYSQL只有 INNODB和BDB类型的数据表才⽀持事务处理,其他的类型是不⽀持的!
MYSQL5.0 WINXP下测试通过~ ^_^
代码如下复制代码
mysql> use test;
Database changed
mysql> CREATE TABLE `dbtest`(
-> id int(4)
-> ) TYPE=INNODB;
Query OK, 0 rows affected, 1 warning (0.05 sec)
mysql> * from dbtest
-> ;
Empty set (0.01 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into dbtest values(5);
Query OK, 1 row affected (0.00 sec)
mysql> insert into dbtest value(6);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from dbtest;
+------+
| id |
制定绩效目标的smart原则+------+
| 5 |
| 6 |
+------+
2 rows in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into dbtest values(7);
Query OK, 1 row affected (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from dbtest;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.00 sec)
mysql> mysql事务处理
php代码实现事务的处理可以通过PHP预定义类mysqli的以下⽅法实现。
autocommit(boolean):该⽅法⽤于限定查询结果是否⾃动提交,如果该⽅法的参数为true则⾃动提交,如果参数为false则关闭⾃动提交。MySQL数据库默认为⾃动提交。
rollback():利⽤mysqli类中的该⽅法可以实现事务的回滚。
commit():利⽤该⽅法可以实现提交所有查询。
名片设计模板网站代码如下复制代码
<?php
_once("conn.php");
$id=$_GET[id];
$conn->autocommit(false);
if(!$conn->query("delete from tb_sco where id='".$id."'"))
{
$conn->rollback();
}
if(!$conn->query("delete from tb_stu where id='".$id."'"))
{
$conn->rollback();
}
$conn->commit();
$conn->autocommit(true);
echo "ok"
>
列⼆
代码如下复制代码
<?php
require('connectDB.php'); //建⽴数据库连接
mssql_query("BEGIN TRANSACTION DEPS02_DEL"); //开始事务
$delete_dep_sql="DELETE FROM TBLDEPARTMENT WHERE
DEPTID='{$_GET[deptid]}'";
// echo $delete_dep_sql."<br>";
mssql_query($delete_dep_sql); //操作数据库
/
/ var_dump($del_result);
$delete_result = mssql_query("select @@ROWCOUNT as id");
$delete_info = mssql_fetch_array($delete_result);
$delete_rows = $delete_info[0];
// var_dump($delete_rows);
mssql_free_result($delete_result);
echo "<script language=>";
if(true){ //判断是否回滚提交
mssql_query("COMMIT TRANSACTION DEPS02_DEL"); //提交事务
echo "alert('delete success!');";
}else{
mssql_query("ROLLBACK TRANSACTION DEPS02_DEL"); //回滚事务
echo "alert('delete faile!');";
}
echo "</script>";mssql_close();
>
例3
MySQL的事务处理在处理实际问题中有着⼴泛且重要的应⽤,最常见的应⽤如银⾏转账业务、电⼦商务⽀付业务等等。但是,值得注意的是,MySQL的事务处理功能在MYSIAM存储引擎中是不⽀持的,在InnoDB存储引擎中是⽀持的。现在上传⼀段代码,作为引导认识MySQL 事务处理的开始,简单的实例,但融汇思想,相信会有很⼤的帮助。
代码如下复制代码
<?php
$conn=mysql_connect('localhost','root','yourpassword')or die(mysql_error());
mysql_select_db('transaction',$conn);
mysql_query('set names utf8');
//创建事务
mysql_query('START TRANSACTION') or die(mysql_error());
$sqlA="update A set account=account-1";
if(!mysql_query($sqlA)){
mysql_query('ROLLBACK') or exit(mysql_error());//判断当执⾏失
败时回滚
exit();
}
$sqlB="update B set account=account+1";
if(!mysql_query($sqlB)){
mysql_query('ROLLBACK') or exit(mysql_error());//判断当执⾏失
败时回滚
exit();
}
mysql_query('COMMIT')or die(mysql_error());//执⾏事务
mysql_close($conn);
>
以上代码可以作为模拟银⾏转账业务的事务流程。以表A、B分别表⽰两个已在银⾏开户的账户,当账户A执⾏转出1元给账户B的操作时,如果操作执⾏失败,转出将会回滚⾄原始状态,不继续向下执⾏动作。反之,如果操作执⾏成功,则账户B可⽤余额将增加1元,否则事务回滚⾄原始状态。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论