getprivateprofilestring读不到数据_数据库的死锁原因 和 处理办法

数据库的死锁: 和 java的 死锁类似 ,条件 ,两个事务(线程) ,事务1 和事务2 ,事务1 要拿到 了 锁a ,等待 锁 b ,事务2 拿到了 锁b ,等待锁a。 这时候就死锁了。

备注: java 我们很明显的 知道什么时候加的锁什么时候释放锁,比如 synch 方法( 进入方法前获取锁,方法执行完毕释放锁 ), synch 语句块( 进入语句块 和退出 语句块 ) ,lock 接口( lock 和 unlock 的时候 )。

    数据库加锁在什么时候呢?

    mysql 为例, mysql 的写是加的 写锁,也就是独占锁, mysql innodb 的读 因为有个非锁定读的机制,所以 读的时候不需要加锁,并且读的时候别的事务 也能改这份数据,但是 读线程读到的依旧是 事务启动的时候的数据( RR 事务隔离级别 描述的 可重复读)。

    也就是 innodb 读不加锁。但是写加了锁,在什么时候加锁呢? 在我们执行一条 update 语句的时候。 在什么时候释放锁呢? 在事务提交的时候。

时间  事务a 开始 事务b 开始

t1   1 随便 读点啥..... 1 随便 搞点啥

t2  2 update 资源 1 锁 资源1,如果拿不到就等待 2 update 资源2 锁定资源2 ,锁不到就等待

t3    3 随便搞搞点 啥                    3 随便搞点啥

t4   4 update 资源 2 锁资源2,如果拿不到就等待 4 update 资源1 锁定资源1 ,锁不到就等待

上面说过 锁会在事务提交的时候释放,所以 两个事务就锁死了。

做实验的时候可以 关闭mysql 的自动提交 ,然后2 个窗口敲 。或者 java代码里面通过 java的 CyclicBarrier 让两个事务 在 t3 的时间点对齐 。

然后说说数据库死锁的解决办法。

1 编码规范有计划的顺序更新数据避免出现 相互抱锁的 问题。

2 数据库线程有超时 机制,一个事务超时,锁被释放,另一个线程就会向下执行了。

3 数据库有死锁检查 机制,发现死锁的时候 会让 更新少的 一个 事务回滚。

  innodb_deadlock_detect=on 之歌参数默认是打开的,也就是mysql 默认就会处理死锁问题。处理方式就是回滚 跟新少的事务。

4 mysql 如果关闭了 死锁回滚 可以配置 等锁超时 时间 innodb_lock_wait_timeout 。 默认是 5 0 秒。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值