mysql的事务处理与锁表

来源:互联网 发布:短域名生成 编辑:程序博客网 时间:2024/06/03 20:56

数据库的事务处理可以保证一组处理结果的正确性。mysql中只有INNODB和BDB引擎的数据表才支持事务处理,对于不支持事务的MyISAM引擎数据库可以使用表锁定的方法来实现相同的功能。

  mysql的事务处理主要有两种方法来实现。

  1、用begin,rollback,commit来实现。

  begin 开始一个事务

  rollback 事务回滚

  commit 事务确认

  Php代码

  1. $conn = mysql_connect('localhost','root','root') or die ("数据连接错误!!!");
  2. mysql_select_db('test',$conn);
  3. mysql_query("set names 'utf8'");
  4. //开始一个事务
  5. mysql_query("BEGIN"); //或者mysql_query("START TRANSACTION");
  6. $sql = "INSERT INTO `t_user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";
  7. $sql2 = "INSERT INTO `t_user` (`did`, `username`, `sex`) VALUES (NULL, 'test1', '0')";//这条是故意写错
  8. $res = mysql_query($sql);
  9. $res1 = mysql_query($sql2);
  10. if($res && $res1){
  11. mysql_query("COMMIT");
  12. echo '提交成功。';
  13. }else{
  14. mysql_query("ROLLBACK");
  15. echo '数据回滚。';
  16. }
  17. mysql_query("END");

  2、直接用set来改变mysql的自动提交模式

  MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过

  set autocommit=0 禁止自动提交

  set autocommit=1 开启自动提交

  Php代码

  1. $conn = mysql_connect('localhost','root','root') or die ("数据连接错误!!!");
  2. mysql_select_db('test',$conn);
  3. mysql_query("set names 'utf8'");
  4. mysql_query("SET AUTOCOMMIT=0"); //设置mysql不自动提交,需自行用commit语句提交
  5. $sql = "INSERT INTO `t_user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";
  6. $sql2 = "INSERT INTO `t_user` (`did`, `username`, `sex`) VALUES (NULL, 'test1', '0')";//这条故意写错
  7. $res = mysql_query($sql);
  8. $res1 = mysql_query($sql2);
  9. if($res && $res1){
  10. mysql_query("COMMIT");
  11. echo '提交成功。';
  12. }else{
  13. mysql_query("ROLLBACK");
  14. echo '数据回滚。';
  15. }
  16. mysql_query("END"); //事务处理完时别忘记mysql_query("SET AUTOCOMMIT=1");自动提交

  对于不支持事务的MyISAM引擎数据库可以使用表锁定的方法来实现

  MyISAM & InnoDB 都支持,LOCK TABLES可以锁定用于当前线程的表。如果表被其它线程锁定,则造成堵塞,直到可以获取所有锁定为止。UNLOCK TABLES可以释放被当前线程保持的任何锁定。当线程发布另一个LOCK TABLES时,或当与服务器的连接被关闭时,所有由当前线程锁定的表被隐含地解锁。

  Php代码

  1. mysql_query("LOCK TABLES `t_user` WRITE");//锁住`user`表
  2. $sql = "INSERT INTO `t_user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";
  3. $res = mysql_query($sql);
  4. if($res){
  5. echo '提交成功。!';
  6. }else{
  7. echo '失败!';
  8. }
  9. mysql_query("UNLOCK TABLES");//解除锁定

  如果操作表比较多,采用断点调试的时候,在事务处理完成之前(COMMIT)查看数据库的相关表是看不到表中数据的变化的。

  下面是在mysql存储过程中使用事务处理的一个例子。

  Java代码

  1. CREATE PROCEDURE TransTest(in p1 VARCHAR(20),in p2 VARCHAR(50))
  2. BEGIN
  3. declare err int default 0;
  4. /*如果出现sql异常,则将err设置为1后继续执行后面的操作 */
  5. declare continue handler for sqlexception set err=1; -- 出错处理
  6. set autocommit = 0;
  7. insert into sy_queryconfig(syq_id) values(p1);
  8. insert into sy_queryconfig(syq_id) values(p2);
  9. if err=1 then
  10. ROLLBACK;
  11. ELSE
  12. COMMIT;
  13. end if;
  14. END

  PS:附加一个mysql数据库在delete表数据的时候,不能用别名操作,例如:

  delete from t_user where id in (1,2);//此写法正确delete from t_user t where t.id in (1,2);//此写法错误

  mysql就是这么任性!

技术分享:凯哥学堂

0 0
原创粉丝点击