一、事物的概念
事务----一组有序的数据库操作。
原子性:事务不可分割。
隔离性:多个事务彼此隔离不受影响。
一致性:状态一致,全部成功(submit)or全部失败(rollback)。
持久性:事务的提交的结果,将持久保存。
二、Yii2事务的使用
$transaction = $connection->beginTransaction();
try {
$order = new Order($customer);
$order->save();
$order->addItems($items);
$transaction->commit();
} catch (\Exception $e) {
$transaction->rollBack();
throw $e;
}
开启事务时可以设置事务隔离级别:
$transaction = $connection->beginTransaction(Transaction::READ_COMMITTED);
三、事务并发问题
1.第一类丢失更新:在没有事务隔离下,两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了。
2.脏读:指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库。第二个事务也访问了该数据并且使用了修改后的数据,这时第一个事务失败回滚,导致第二个事务的脏读。
3.不可重复读:在一个事务里重复读取一个数据,而在第二个事务里对该数据访问并做了修改,在第一个事务中发生两次或多次读取数据不一样。
4.第二类丢失更新:不可重复读的特例。两个事务对同一数据读取,第一个事务对数据进行了修改,第二个事务也对数据进行了修改,造成第一次写操作失败。
5.幻读:第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
四、事务隔离级别
1.READ_UNCOMMITTED
这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。
可以解决第一类丢失更新问题。
2.READ_COMMITTED
保证一个事务修改的数据提交后才能被另外一个事务读取,即另外一个事务不能读取该事务未提交的数据。
解决第一类丢失更新和脏读的问题,但会出现不可重复读、第二类丢失更新的问题,幻读问题
3.REPEATABLE_READ(默认)
保证一个事务相同条件下前后两次获取的数据是一致的
解决第一类丢失更新,脏读、不可重复读、第二类丢失更新的问题,但会出幻读。
4.SERIALIZABLE
事务被处理为顺序执行。
解决所有问题,但是读取的每行数据都加锁,会导致大量的锁征用问题,性能最差。