一.事务的特性
- 原子性
即不可分割性:事务中包含的逻辑不可分割.事务中的操作,要么全部成功提交(commit),要么全部回滚(rollback).
- 一致性
即事务执行前后数据的完整性。一个事物执行前和执行后都必须保持一致性状态。举个例子:两个账户总存款1000元,无论进行多少次相互转账,都应该保持总存款1000元。
- 隔离性
即事务在执行期间不应该受到其他事物的影响。
- 持久性
即数据持久性.一但事务执行成功,那么数据应该永久保存到磁盘上.
二.读问题
3种读问题
- 脏读
一个事务读到另一个事务未提交的数据。
- 不可重复读
一个事务读到另一个事务已提交的数据。某些情况的这并不是问题,但在例如取款事务中,A在取款过程中,B向A转账100,将造成余额结果的不同。
- 幻读
强调新增数据引发的读问题。例如银行在一事务中两次统计总金额,过程中新增了一个存款账户,造成前后数据的不同。
不可重复读与幻读的区别
**不可重读读在于update和delete,而幻读强调的是insert。**幻读需要用Serializable隔离级别解决。
4种隔离级别:
- Read Uncommitted
最低隔离级别,读未提交,引发‘脏读’问题。
- Read Committed
读已提交,引发‘不可重复读’问题。
- Repeatable Read
可重复读,引发幻读问题
- Serializable
可串行化;若一个连接设置为串行化,那么先打开的事务就有最先执行的权力,其他事物只能排队等待。但导致性能问题。
注意:数据库设置隔离级别应该在事务开启之前。
三.写问题
- 丢失更新
一个事务的commit或rollback导致另一个先前提交的事务丢失更新。
例如:有一个存款账户,A事务更改其用户名,B事务更改其存款金额,A事务先提交,B事务后提交,这将造成丢失更新。因为在B事务中,用户名没有改变。
四.悲观锁/乐观锁
- 悲观锁
在查询时,添加 FOR UPDATE.
例: SELECT * FROM table FOR UPDATE;
- 乐观锁
要求人为加入版本控制.事务对比自己与数据库的version,若不一致,则不允许提交,需先更新.