文章目录
1.事务里面的语句出错时并不会主动回滚,需要用户主动执行回滚指令
2.事务开始后,如果没有主动执行回滚或者提交指令,事务始终在执行中
3.事务执行中,涉及到的表被锁定,其它会话可以查询,但是不能修改
4.执行回滚指令,事务中的执行计划被舍弃,事务结束
5.执行提交指令,事务中的执行计划被切实执行,而且这个切实执行还不可能报错,事务结束
事务四大特征
1.原子性,事务是不可分割的最小操作单位,要么同时成功,要么同时失败
2.持久性,一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的数据
3.隔离性,隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
4.一致性,事务执行前后的数据完整性保持一致。拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
多事务并发存在的问题
1.脏读,一个事务,读取到另一个事务中没有提交的数据
2.不可重复读(虚读) ,在同一个事务中,两次读取到的数据不一样
3.幻读
示例(1):
事务 T 查询某记录是否存在,查询结果是不存在,于是插入这条记录,但执行插入语句时发现此记录已存在(其它事务插入了数据),无法插入,此时就发生了幻读。
示例(2):
事务 T1 将表中所有行的字段 A 的值从 1
修改为 2
,这时事务 T2 又对这个表插入了一行数据,而且这行数据的字段 A 的值就是 1
并且提交给数据库。如果事务 T1 再查看刚刚修改的数据,会发现还有一行没有修改,其实这行数据事务 T2 添加进去的,就好像产生幻觉一样,这就是发生了幻读。
事务隔离级别
1.Read Uncommitted
,表示读取未提交的,效率最高,但是安全级别最低,会产生脏读、不可重复读、幻读三种问题
2.Read Committed
,读取已提交的,效率其次,安全级别稍好,不会产生脏读问题,但是会产生不可重复读和幻读两种问题。Oracle 默认此级别
3.Repeatable Read
,可重复读,效率还行,安全级别不错,不会产生脏读和不可重复读的问题,但是会产生幻读问题。MySQL 默认此级别
4.Serializable
,串行化,效率比较低,安全级别最高,不会产生任何问题。原因:某个事务对某个表的数据进行了修改会加表级排他锁;如果查询某个表的数据则会加表级共享锁
查询数据库的隔离级别
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set, 1 warning (0.00 sec)
如果是 macOS,事务隔离级别的系统变量是:
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| SERIALIZABLE |
+-------------------------+
1 row in set (0.00 sec)
设置数据库隔离级别
# 设置全局级别的
set global transaction isolation level repeatable-read
# 设置会话级别的
set session transaction isolation level repeatable-read