初始化连接

MYSQL *mysql = mysql_init(NULL);

处理结果

MYSQL_RES mysql_store_result(MYSQL *mysql);
//获取由mysql_query()函数返回的结果,注意查询成功是0,失败为非0.所以使用时一般if(。。。){}

void mysql_free_result(MYSQL_RES *result);
//释放数据结构MYSQL_RES占据的内存空间

my_ulonglong mysql_num_rows(MYSQL_RES *result);
//SQL语句结果的行数

unsigned int mysql_num_fields(MYSQL_RES *result);
///SQL语句结果的列数

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
//从结果当中取出一行

事务特性ACID

原子性atomicity

  • 整个事务的操作要嘛全部commit,要嘛全部rollback,不可分割

一致性consistency

  • 狭义类似于物质守恒,数据从一个状态,通过事务要嘛不变,要嘛一致性地演变为另一种状态

隔离性isolation

  • 事务之间的关联性
  • 关联性可强可弱

持久性durability

一旦事务commit或rollback,事务对数据库的改变应当是永久的

数据操作可能遇到的问题

脏读(Dirty read)

一个事务读取到了另一个事务还未提交的数据

  • a给b转账,a扣款是个过程。当下时刻本该是扣了款的状态,在此过程却有人去读它的余额,因为该过程未完成(还没commit),读到的是没扣款的状态。

不可重复读(Nonrepeatable read)

同一事务,针对同一数据,前后读取数据却不同

  • a事务前后读了两次余额,但在两次读的中间,b事务对余额做了修改,便导致读到的余额不同了

幻读(Phantom read)

一个事务内读到的条目数变了

  • 其实就跟不可重复读原理类似,都是在两次读的中间,数据被修改了。只是不可重复读是读到了数据内容变化(如update set),而幻读读到了数据条目数的变化(如 insert into)

隔离级别

适用情况:俩数据库连接,一个在增删改,另一个在查

查看和修改隔离级别

 SELECT @@GLOBAL.TRANSACTION_ISOLATION; -- 查看整个数据的设置
 SELECT @@SESSION.TRANSACTION_ISOLATION; -- 查看一个连接的隔离级别
 SET GLOBAL TRANSACTION ISOLATION LEVEL [SERIALIZABLE | REPEATABLE READ| ...];
 SET SESSION TRANSACTION ISOLATION LEVEL [SERIALIZABLE | REPEATABLE READ| ...];

如:

 set global transaction isolation level read uncommitted;
 set global transaction isolation level repeatable read;

提前说明,实际上这些隔离级别都是针对读端的,只是在读端事务中,查询的结果会因为隔离级别的不同而不同。

不过navicat图形化进行查询,似乎情况有所不同,比如即使已全局设置了隔离级别为读已提交,事务进行数据修改后未提交,navicat图形化查询也是修改后的数据。rollback之后数据又回来了。似乎级别默认是读未提交且不会被直接更改。

读未提交(READ UNCOMMITE)

READ UNCOMMITED

事务的修改,即使没有提交,对其他事务也可见

会产生问题:脏读,不可重复读,幻读

读已提交(READ COMMITED)

READ COMMITED

事物的修改在提交前,其他事务不可见

会产生问题:不可重复读,幻读。

但不会产生脏读了

可重复读(REPEATABLE READ)

REPEATABLE READ

MySQL的默认隔离级别

一个事务开始后,保证多次读取的结果一致

  • 在REPEATABLE READ隔离级别下,MySQL会创建一个一致性视图,即事务开始时的视图。所有的SELECT语句将基于这个视图返回结果,即使其他事务进行了更新,也不会影响当前事务的视图。
  • 所以一般情况下直观来说,读端事务在事务开始时创建一个快照表,之后就对着这个快照表查数据了,不会因为其他事务对数据的修改而改变查询的结果

仍会存在一部分幻读问题,解决了脏读与不可重复读

  • 关于幻读,该隔离级别演示结果上看起来没有幻读问题,实际上在MySQl的可重复读隔离级别上,仍是存在幻读的问题

序列化(SERIALIZABLE)

SERIALIZABLE

强制事务串行执行,在事务读取每一行数据时都上锁,以保证事务的先后顺序。也就因此不存在多个事务同时执行的情况了(无上述问题)。

例如一个事务,仅一句select * from table 就会锁住table中数据。在该事务commit前其他事务都不可增删改

各隔离级别的对比

隔离级别 脏读 不可重复读 虚幻读
读未提交(read uncommitted)
读已提交(read committed) X
可重复读(repeatable read) X X √-×
串行化(serializable) X X X

更新时间: