编程(45)----------事务

MySQL当中的事务, 说起来比较抽象, 举例说明. 

假设账户A要往账户B中转账1000, 就数据库而言其执行顺序大概是先往A账户中扣除1000, 再往B账户中数据加上1000. 但是, 如果在已扣除A账户余额后, 且B账户未更新时断电, 或者发生其他情况, 这样的操作就无法达成.

为了避免这样的情况, 就需要将上诉两个操作给绑定到一起. 要么都执行, 要么都不执行. 但是这个不执行并非是真的不执行, 而是回溯. 比如停电后, 由于两个操作被绑定为一个事务. 但此时又只执行了其中一个. 那么在再次通电以后, 会将数据回溯到第一步操作执行之前. 执行了但又回溯了, 视为未执行.

start transaction; --事务开启

update account set money=money-2000  where name = 'A';

update account set money=money+2000  where name = 'B';

commit; --事务提交(到此事务结束)

事务的使用并不算复杂, 但重点要理解事务的几个特征:

1. 原子性. 

这也是事务所使用的目的, 即保持某些操作具备不可分割的原子性. 保证不会在执行途中出现只执行一部分另一部分不执行的情况.

2. 一致性.

在事务中进行查询某个数据时, 无论查询多少次, 查询的数据都应该是合理的. 比如微信钱包余额. 不可能在不使用的情况下, 每次看数字都不一样.

3. 持久性.

事务所修改的内容是数据库中的数据, 而数据库中的数据是写在硬盘上的, 因此具有持久性.

4. 隔离性.

这是在并发编程中所考虑的问题. 还是举例说明:

假设两个事务A B, 事务A正在对数据进行修改的过程中, 还未进行提交, 事务B就对这个数据进行了读取, 这样读到的数据是不完整的, 可被成为脏读. 解决办法就是在事务中针对写操作加锁

在此基础上还存在一种特殊情况. 假设事务1提交了数据, 随后事务2开始读数据, 但同时事务3又提交了数据. 也就是说在事务2中多次读数据读出来的是不同结果. 而需求是在一个事务中, 读取的数据应该是相同的. 这是不可重复读问题. 解决方法是在一个事务中对读加锁.

还存在一种更特殊的情况. 在事务1提交数据后, 事务2进行读取时, 多次读取发现数据的值虽然是一样的, 但是结果集不一样. 比如本身读取数字5, 反复读取确实也是数字5, 没变的值. 但是在某一次读取时, 却多出一个除5以外的值. 这种情况被称为幻读. 在这样的情况下, 读加锁与写加锁其实已经无效化了, 只能实行事务串行化. 即单线程进行事务的处理.

------------------------------最后编辑于2023.7.11 上午十一点左右

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值