什么是事务
通过一组逻辑操作单元(一组DML——sql语句),将数据从一种状态切换到另外一种状态。
事务的特点(遵循ACID原则)
原子性(atomicity):最小的执行单元。(要么全成功,有一条失败则回滚到最初状态)要么都执行,要么都回滚
一致性(consistrncy):保证数据的状态操作前和操作后保持一致,即事务的执行使得数据库从一种正确状态转换为另一种正确的状态。
隔离性(isolation):多个事务同时操作相同数据库的同一个数据时,一个事务的执行不受另外一个事务的干扰
持久性(durability):一个事务一旦提交,则数据将持久化到本地,除非其他事务对其进行修改
事务的作用:
事务管理对于企业级应用而言至关重要,它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性。就像银行的自动提款机ATM,通常ATM都可以正常为客户服务,但是也难免遇到操作过程中及其突然出故障的情况,此时,事务就必须确保出故障前对账户的操作不生效,就像用户刚才完全没有使用过ATM机一样,以保证用户和银行的利益都不受损失。
相关步骤:
1、开启事务
2、编写事务的一组逻辑操作单元(多条sql语句)
3、提交事务或回滚事务
事务控制语句:
begin/ start transaction:开启事务
commit:提交事务
rollback:回滚事务
set autocommit=0 禁止自动提交事务(开启事务)
set autocommit=1 开启自动提交事务
事务的分类:
隐式事务,没有明显的开启和结束事务的标志
比如 insert、update、delete语句本身就是一个事务
显式事务,具有明显的开启和结束事务的标志
1、开启事务
取消自动提交事务的功能
2、编写事务的一组逻辑操作单元(多条sql语句)
insert
update
delete
3、提交事务或回滚事务
使用到的关键字
set autocommit=0;
start transaction;
commit;
rollback;
savepoint 断点
commit to 断点
rollback to 断点
事务并发问题如何发生?
当多个事务同时操作同一个数据库的相同数据时
事务的并发问题有哪些?
脏读:一个事务读取到了另外一个事务未提交的数据
不可重复读:同一个事务中,多次读取某个数据得到的数据不一致
幻读:一个事务读取数据时,另外一个事务进行更新,导致第一个事务读取到了没有更新的数据
如何避免事务的并发问题?
通过设置事务的隔离级别,事务的隔离级别就是为了解决上述的问题诞生的。事务的隔离级别越高,在并发的情况下产生的问题就越少,但同时付出的性能消耗也将越大,因此很多时候必须在并发性和性能之间做一个权衡。
1. read uncommitted(读未提交):最低级别,任何情况都无法保证
2. read committed(读已提交):可避免脏读的发生
3. repeatable read(可重复读):可避免脏读,不可重复读的发生
4. serializable(串行化):可避免脏读,不可重复读,幻读的发生
事务隔离级别能否解决并发问题的图表:
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交(read uncommitted) | 是 | 是 | 是 |
不可重复读(read committed) | 否 | 是 | 是 |
可重复读(repeatable read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
级别越高,执行效率越低。像serializable,是用锁表的方式使得其他线程只能在锁外等候,用何种隔离级别应根据实际情况,
mysql支持四种隔离级别,默认级别repeatable read(可重复读)
oracle支持serializable(串行化)和read commited(读已提交)这两种级别,默认为read commited;
-- 设置隔离级别:
set session|global transaction isolation level 隔离级别名;
set tx_isolation='隔离级别名称';
-- 查看隔离级别:
select @@tx_isolation;
show variables like '%tx_isolation';
-- glogal:指设置的事务隔离级别全局生效,但需要重启mysql会话
-- session:指设置的事务隔离级别仅在本次会话中生效
如有不足,欢迎留言指正。望不吝赐教。。。