一、事务简介
myisam存储引擎:不支持事务。是自动commit的。
innodb存储引擎:支持事务,默认也是自动commit,autocommit=0,每条语句都是一个单独的事务。如果不想自动提交,可以使用事务来保持ACID,事务的几个操作步骤:
1.begin; //开始事务 (也可以用start transaction或者begin work,使用这三个后,autocommit=0暂时禁用,直到rollback或commit)
2.update …… //做一些操作
3.rollback; //回滚,回到begin前的状态
4.update ….. //做一些事情
5.commit // 提交事务
注:如果autocommit=1,则每条sql语句都是一个事务;如果autocommit=0,则需要多个sql后,执行commit,才算一个事务。
事务有ACID的特性,分别是“atomicity”,“consistency”,”isolation”,”durability”。
二、事务的原理:
一致性读:
注:在事务的过程中,其他connection读取的数据都是begin前的数据,这称为consistent reading(一致性读),说到这里,就要提一下innodb的四个“事务隔离级别”(transaction isolation levels)了。四个事务隔离级别分别是:read_uncommited, read_commited, repeatable_read和seriallizable,默认的隔离级别是repatable_read。 (详见:
https://dev.mysql.com/doc/refman/5.5/en/innodb-transaction-isolation-levels.html#isolevel_read-committed 和 https://dev.mysql.com/doc/refman/5.5/en/innodb-consistent-read.html)
回到上面的consistent reading(一致性读),一致性读的官方定义是这样的:一个一致性读操作使用snapshot信息去显示基于某个时间点的query结果,而不去考虑同时在运行的其他事务对数据的改变。 如果query结果被其他事务修改了,初始数据会根据“undo log”重写。
启用“repeatable read”隔离级别的时候,快照是以第一次读操作为时间点的;启用“read commited”隔离级别时,快照会根据每个“一致性读”的时间持续更新。在innodb的select状态为“read_commited” 和“repeatable read”的时候,一致性读是默认的模型,因为一致性读不会为它读的表加锁,一致性读对某个表操作后,其他session可以随便修改这个表。
三、事务隔离级别
四个事务隔离级别分别是:read_uncommited, read_commited, repeatable_read和seriallizable,默认的隔离级别是repatable_read。
read_uncommited:并发度高,不上锁。其他事务的操作会直接反映到当前事务的select结果中。
read_commited:打snapshot;其他事务提交后,才会反映到当前事务的select结果中。瞬时数据、没有提交的、脏数据都不会被读到。
repeatable_read:打snapshot,并以此为准,其他事务所有操作不影响。
serializable:把所有事务排序,依次执行
MySQL中,实现了这四种隔离级别,分别有可能产生问题如下所示:
四种隔离级别
四、JDBC使用事务
JDBC使用connection管理事务。默认是conn.setAutoCommit(True)的,也就是每一条语句都是一个单独的事务。
如果想将多条语句写成一个事务,可以用conn.setAutoCommit(False)。案例:
try{
con.setAutoCommit(false);//开启事务(不自动提交) ......
con.commit();//try的最后提交事务
} catch() {
con.rollback();//回滚事务
}
网友评论