事务
事务:逻辑上的一组操作 这组操作要么一起成功,要么一起失败。比如 前提 :张三 和 李四账户 各有 2000元。 事务:张三 给李四转账1000元。这个事务 就包括两个操作:从张三账户扣除1000元, 给李四账户 增加1000元。
事务四大特性:
原子性:事务是一个不可分割的单位,这组操作 要么全部发生,要么全部不发生。
一致性:事务 执行前后,数据 完整性保持一致。 比如张三给李四转账的事务,转账前,张三和李四 账户的钱总共 是4000。转账后 张三和李四的钱总共也是4000。
隔离性:多个用户 并发访问 数据的时候,一个用户的事务 不应该 受到 其他用户事务的干扰。即:不能两个事务 同时 对一张表 就行操作。可以 设置 事务的隔离级别 来 保证事务的隔离性。
持久性:一个事务 一旦 被提交,对数据库中 数据的修改是永久性的。
事务的隔离性和隔离级别 参考数据库事务隔离级别-- 脏读、幻读、不可重复读(清晰解释)
事务的隔离性:一个事务的执行的时候 不允许其它事务 干扰。
事务的隔离性可能 引发的安全问题有3种:脏读,不可重复读,幻读。事务的隔离级别 就是来解决这些问题的。事务的隔离级别有四种:读未提交,读已提交,可重复读 和串行读。
脏读:事务1 可以 读取到 事务2 没有提交得修改 会导致脏读。情景:( 事务1 发工资)发工资 领导把5000元打到 员工账户上,但是该事务未提交,( 事务2 操作1 员工查看工资)而员工 正好去查看 账户,发现工资已到账时5000元,非常高兴。可是 领导发现5000元不对,应该是2000元,修改金额后,将事务提交。( 事务2 操作2 员工再次查看工资)员工再去查看账户,发现工资只有2000元,空欢喜一场。 这是因为 在事务1执行的时候,没有把事务涉及到的数据 隔离,所以才导致了事务2 的脏读。事务1是 update 操作。脏读 是update 操作 涉及到的数据 没有隔离引起的。
不可重复读:事务1读取了数据,事务2更新了并提交了数据,事务1再去读取改数据时,数据已经发生了改变。 情景(事务1 老公消费)singo拿着工资卡去消费,系统读取到卡里确实有2000元,(事务2 老婆转账)而此时她的老婆也正好在网上转账,把singo工资卡的2000元转到另一账户,并在 singo之前提交了事务,(事务1 老公消费扣款)当singo扣款时,系统检查到singo的工资卡已经没有钱,扣款失败,singo十分纳闷,明明卡里有钱,为 何...... 这是因为 在事务1执行的时候,没有把事务1涉及到的数据隔离,所以才导致了事务1的 不可重复读。不可重复读 是 select 操作 涉及到的数据 没有隔离引起的。
幻读:是事务1 查询 出结果有10条,期间事务2又insert 或者 delete掉了2条数据并提交了事务,事务1再次查询,发现和第一次读的 记录条数不一样。 幻读 重点是delete 和 insert。
隔离级别-读未提交:没有对数据 隔离,所有对某条数据的 CRUD 操作都可以同时 进行。可能会带来的安全隐患:脏读,不可重复读,幻读。为了解决 脏读的问题,就把隔离级别设置 为读已提交。
隔离级别-读已提交: 是把 update 这种事务涉及到的数据 隔离起来。 如果对某条数据进行 update 操作时,就把这条数据 隔离,其它对这条数据的事务不能执行。它可以解决 脏读 的问题。
隔离级别-重复读:如果事务1 已经读取了数据,事务2 是不能 对该事务涉及到的数据进行修改。 也就是说 在老公去消费的时候,已经读取了银行卡金额,这时候 老婆是不能在此时转账的。 重复读这种隔离级别 就是把 读取事务涉及到的数据也隔离起来。如果 事务1 读取了 某条数据,那么在这个事务执行完执行, 其它对这条数据的操作不能执行。
隔离级别-序列化:强制 事务串行执行。
Oracle数据库默认是 Commited Read. Mysql 数据库默认是 Repeated Read。