Rumah pangkalan data tutorial mysql mysql事务回滚使用与常见问题介绍

mysql事务回滚使用与常见问题介绍

Jun 07, 2016 pm 05:53 PM
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进程来进行回收。

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Hubungan antara pengguna dan pangkalan data MySQL Hubungan antara pengguna dan pangkalan data MySQL Apr 08, 2025 pm 07:15 PM

Dalam pangkalan data MySQL, hubungan antara pengguna dan pangkalan data ditakrifkan oleh kebenaran dan jadual. Pengguna mempunyai nama pengguna dan kata laluan untuk mengakses pangkalan data. Kebenaran diberikan melalui perintah geran, sementara jadual dibuat oleh perintah membuat jadual. Untuk mewujudkan hubungan antara pengguna dan pangkalan data, anda perlu membuat pangkalan data, membuat pengguna, dan kemudian memberikan kebenaran.

Adakah Mysql perlu membayar Adakah Mysql perlu membayar Apr 08, 2025 pm 05:36 PM

MySQL mempunyai versi komuniti percuma dan versi perusahaan berbayar. Versi komuniti boleh digunakan dan diubahsuai secara percuma, tetapi sokongannya terhad dan sesuai untuk aplikasi dengan keperluan kestabilan yang rendah dan keupayaan teknikal yang kuat. Edisi Enterprise menyediakan sokongan komersil yang komprehensif untuk aplikasi yang memerlukan pangkalan data yang stabil, boleh dipercayai, berprestasi tinggi dan bersedia membayar sokongan. Faktor yang dipertimbangkan apabila memilih versi termasuk kritikal aplikasi, belanjawan, dan kemahiran teknikal. Tidak ada pilihan yang sempurna, hanya pilihan yang paling sesuai, dan anda perlu memilih dengan teliti mengikut keadaan tertentu.

Integrasi RDS MySQL dengan Redshift Zero ETL Integrasi RDS MySQL dengan Redshift Zero ETL Apr 08, 2025 pm 07:06 PM

Penyederhanaan Integrasi Data: AmazonRDSMYSQL dan Integrasi Data Integrasi Zero ETL Redshift adalah di tengah-tengah organisasi yang didorong oleh data. Proses tradisional ETL (ekstrak, menukar, beban) adalah kompleks dan memakan masa, terutamanya apabila mengintegrasikan pangkalan data (seperti Amazonrdsmysql) dengan gudang data (seperti redshift). Walau bagaimanapun, AWS menyediakan penyelesaian integrasi ETL sifar yang telah mengubah keadaan ini sepenuhnya, menyediakan penyelesaian yang mudah, hampir-sebenar untuk penghijrahan data dari RDSMYSQL ke redshift. Artikel ini akan menyelam ke integrasi RDSMYSQL Zero ETL dengan redshift, menjelaskan bagaimana ia berfungsi dan kelebihan yang dibawa kepada jurutera dan pemaju data.

Cara Mengisi Nama Pengguna dan Kata Laluan MySQL Cara Mengisi Nama Pengguna dan Kata Laluan MySQL Apr 08, 2025 pm 07:09 PM

Untuk mengisi nama pengguna dan kata laluan MySQL: 1. Tentukan nama pengguna dan kata laluan; 2. Sambungkan ke pangkalan data; 3. Gunakan nama pengguna dan kata laluan untuk melaksanakan pertanyaan dan arahan.

Pengoptimuman pertanyaan di MySQL adalah penting untuk meningkatkan prestasi pangkalan data, terutama ketika berurusan dengan set data yang besar Pengoptimuman pertanyaan di MySQL adalah penting untuk meningkatkan prestasi pangkalan data, terutama ketika berurusan dengan set data yang besar Apr 08, 2025 pm 07:12 PM

1. Gunakan indeks yang betul untuk mempercepatkan pengambilan data dengan mengurangkan jumlah data yang diimbas memilih*frommployeesWherElast_name = 'Smith'; Jika anda melihat lajur jadual beberapa kali, buat indeks untuk lajur tersebut. Jika anda atau aplikasi anda memerlukan data dari pelbagai lajur mengikut kriteria, buat indeks komposit 2. Elakkan pilih * Hanya lajur yang diperlukan, jika anda memilih semua lajur yang tidak diingini, ini hanya akan memakan lebih banyak pelayan dan menyebabkan pelayan melambatkan pada masa yang tinggi atau kekerapan misalnya, jadual anda

Bagaimana untuk mengoptimumkan prestasi MySQL untuk aplikasi beban tinggi? Bagaimana untuk mengoptimumkan prestasi MySQL untuk aplikasi beban tinggi? Apr 08, 2025 pm 06:03 PM

Panduan Pengoptimuman Prestasi Pangkalan Data MySQL Dalam aplikasi yang berintensifkan sumber, pangkalan data MySQL memainkan peranan penting dan bertanggungjawab untuk menguruskan urus niaga besar-besaran. Walau bagaimanapun, apabila skala aplikasi berkembang, kemunculan prestasi pangkalan data sering menjadi kekangan. Artikel ini akan meneroka satu siri strategi pengoptimuman prestasi MySQL yang berkesan untuk memastikan aplikasi anda tetap cekap dan responsif di bawah beban tinggi. Kami akan menggabungkan kes-kes sebenar untuk menerangkan teknologi utama yang mendalam seperti pengindeksan, pengoptimuman pertanyaan, reka bentuk pangkalan data dan caching. 1. Reka bentuk seni bina pangkalan data dan seni bina pangkalan data yang dioptimumkan adalah asas pengoptimuman prestasi MySQL. Berikut adalah beberapa prinsip teras: Memilih jenis data yang betul dan memilih jenis data terkecil yang memenuhi keperluan bukan sahaja dapat menjimatkan ruang penyimpanan, tetapi juga meningkatkan kelajuan pemprosesan data.

Cara menyalin dan tampal mysql Cara menyalin dan tampal mysql Apr 08, 2025 pm 07:18 PM

Salin dan tampal di MySQL termasuk langkah -langkah berikut: Pilih data, salin dengan Ctrl C (Windows) atau Cmd C (Mac); Klik kanan di lokasi sasaran, pilih Paste atau gunakan Ctrl V (Windows) atau CMD V (MAC); Data yang disalin dimasukkan ke dalam lokasi sasaran, atau menggantikan data sedia ada (bergantung kepada sama ada data sudah ada di lokasi sasaran).

Memahami sifat asid: tiang pangkalan data yang boleh dipercayai Memahami sifat asid: tiang pangkalan data yang boleh dipercayai Apr 08, 2025 pm 06:33 PM

Penjelasan terperinci mengenai atribut asid asid pangkalan data adalah satu set peraturan untuk memastikan kebolehpercayaan dan konsistensi urus niaga pangkalan data. Mereka menentukan bagaimana sistem pangkalan data mengendalikan urus niaga, dan memastikan integriti dan ketepatan data walaupun dalam hal kemalangan sistem, gangguan kuasa, atau pelbagai pengguna akses serentak. Gambaran keseluruhan atribut asid Atomicity: Transaksi dianggap sebagai unit yang tidak dapat dipisahkan. Mana -mana bahagian gagal, keseluruhan transaksi dilancarkan kembali, dan pangkalan data tidak mengekalkan sebarang perubahan. Sebagai contoh, jika pemindahan bank ditolak dari satu akaun tetapi tidak meningkat kepada yang lain, keseluruhan operasi dibatalkan. Begintransaction; UpdateAcCountSsetBalance = Balance-100Wh

See all articles