为什么要有事务?
事务的提出就是为了解决并发情况下保持数据一致性的问题。
事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性。
1.事务的特性(ACID)
1.1、原子性(atomicity)
即不可分割,事务要么全部被执行,要么全部不执行。如果事务的所有子事务全部提交成功,则所有的数据库操作被提交,数据库状态发生变化;如果有子事务失败,则其他子事务的数据库操作被回滚,即数据库回到事务执行前的状态,不会发生状态转换。
1.2、一致性(consistency)
事务的执行使得数据库从一种正确状态转换成另外一种正确状态。
1.3、隔离性(isolation)
在事务正确提交之前,不允许把事务对该数据的改变提供给任何其他事务,即在事务正确提交之前,它可能的结果不应该显示给其他事务。
1.4、持久性(durability)
事务正确提交之后,其结果将永远保存在数据库之中,即使在事务提交之后有了其他故障,事务的处理结果也会得到保存。
2.事务的隔离级别
2.1 READ_UNCOMMITTED(读未提交)
读未提交,即能够读取到没有被提交的数据,所以很明显这个级别的隔离机制无法解决脏读、不可重复读、幻读中的任何一种,因此很少使用。
2.2 READ_COMMITED(读已提交)
读已提交,即能够读到那些已经提交的数据,自然能够防止脏读,但是无法限制不可重复读和幻读。
2.3 REPEATABLE_READ(可重复读)
可重复读,即在数据读出来之后加锁,类似"select * from XXX for update",明确数据读取出来就是为了更新用的,所以要加一把锁,防止别人修改它。REPEATABLE_READ的意思也类似,读取了一条数据,这个事务不结束,别的事务就不可以改这条记录,这样就解决了脏读、不可重复读的问题,但是幻读的问题还是无法解决。
2.4 SERLALIZABLE(串行化)
串行化,最高的事务隔离级别,不管多少事务,挨个运行完一个事务的所有子事务之后才可以执行另外一个事务里面的所有子事务,这样就解决了脏读、不可重复读和幻读的问题了。
3.并发下事务会产生的问题
脏读:事务A读到了事务B还没有提交的数据。
不可重复读(虚读):在一个事务里面读取了两次某个数据,读出来的数据不一致。(添加/更新/删除)
幻读:事务在插入已经检查过不存在的记录时,惊奇的发现这些数据已经存在了,之前的检测获取到的数据 如同鬼影一般。(添加和删除的时候)
4.mysql事物隔离级别查看及修改
查看事务隔离级别使用select @@tx_isolation
修改当前会话事务隔离级别使用SET session TRANSACTION ISOLATION LEVEL Serializable;
(参数可以为:Read uncommitted|Read committed|Repeatable read|Serializable)
修改全局事务隔离级别使用SET global TRANSACTION ISOLATION LEVEL Serializable;
(参数可以为:Read uncommitted|Read committed|Repeatable read|Serializable)
修改了会话的事务隔离级别,比如MyBatis,getSqlSession()的时候,只针对这一次拿到的Session有效;
比如CMD命令行,只对这一次的窗口有效。
START TRANSACTION;--开启事务
COMMIT;--提交
ROLLBACK;--回滚