事务
1.概念
事务是指逻辑上的一组操作,要么全部成功,要不全都不成功。
例如 A 给 B 转账,需要执行两条sql语句:
update user set money=money-100 where name='A';
update user set money=money+100 whwew name='B';
上面两句sql要么一起成功,要么一起失败,但不允许一部分成功,一部分失败。
2. 事务管理
数据库默认支持事务,如果不手动控制事务,一条sql独占一个事务。
- sql手动控制事务
-
start transaction; 开启事务,此代码之后的sql全在一个事务。
-
Commit;--提交事务,此代码以上的sql一起执行。
-
rollback;--回滚事务,此代码以上的sql一起不执行。
-
- jdbc中的事务控制
-
conn.setAutoCommit(false);--开启事务,conn将不会主动提交事务。
-
conn.commit();--提交事务
-
conn.rollback();--回滚事务
-
3. 四大特性 (ACID)
-
原子性(Atomicity)
指事务是一个不可分割的工作单位,事务中的操作要么一起发生,要么一起不发生。 -
一致性(Consistency)
一致性是指事务使得系统从一个一致的状态转换到另一个一致状态,其他事务对其中间状态不可见。 -
隔离性(Isolation)
多个事务同时访问数据库;一个事务不能被其他事务干扰。 -
持久性(Durability)
指一个事务一旦被提交,对数据库的改变是永久的,不可逆,接下来的任何操作都无法逆转。
4. 隔离性
4.1 隔离性分析
- 多个用户同时查询同一条数据,无需隔离。
- 多个用户同时修改一条数据,一定需要隔离。
- 一个用户查询,另一个用户修改,可能会出问题。
4.2 隔离性可能造成的问题
-
脏读
一个事务读到另一个事务未提交的数据。 -
不可重复读
一个事务督导另一个事务已经提交的数据。 -
虚度(幻读)
发生的概率非常低,在读取整表时,多次读取的结果不一致。
5. 数据库的隔离级别
为了防止上述问题,数据库提供了不同的隔离级别。
-
read uncommitted:不做任何隔离,可能会造成所有隔离性问题。
-
read committed:可以防止脏读,但是不能防止不可重复读和虚读。
-
repeatable read:可以防止脏读和不可重复读,但是不能防止虚读。
-
serializable:可以防止所有隔离性问题,但是数据库就被设计成了串行的数据库,性能很低。
隔离级别排序:
-
安全性:read uncommitted<read committed<repeatable read<serializable
-
效率:read uncommitted>read committed>repeatable read>serializable
mysql默认隔离级别:repeatable read
oracle默认隔离级别: read committed
6. 操作数据库的隔离级别
查询数据库的隔离级别:select @@tx_isolation;
设置隔离级别:
set[session/global]transaction isolation level xxxx;
默认是session,表示当前连接有效,global表示全局修改。
7. 数据库中的锁
7.1 共享锁
共享锁可以和共享锁共存,共享锁和排它锁不能共存,在serializable级别下查询时会添加共享锁,其他级别不会。
7.2 排他锁
排它锁和任何锁不能共存,在任何隔离级别下做增删改操作都会添加排它锁。
7.3 死锁
彼此握着对方的资源互不释放,导致彼此都无法继续执行,等待对方释放资源。