数据库的死锁原因 和 处理办法

数据库的死锁: 和 JAVA的 死锁类似,条件,两个事务(线程),事务1 和事务2,事务1 要拿到 了 锁a,等待 锁 b,事务2 拿到了 锁b,等待锁a 。这时候就死锁了 。
【数据库的死锁原因 和 处理办法】 
备注: java 我们很明显的 知道什么时候加的锁什么时候释放锁,比如 synch 方法( 进入方法前获取锁,方法执行完毕释放锁 ),synch 语句块( 进入语句块 和退出 语句块 ),lock 接口( lock 和 unlock 的时候 ) 。
数据库加锁在什么时候呢?
MySQL 为例,mysql 的写是加的 写锁,也就是独占锁,mysql innodb 的读 因为有个非锁定读的机制,所以 读的时候不需要加锁,并且读的时候别的事务 也能改这份数据,但是 读线程读到的依旧是 事务启动的时候的数据( RR 事务隔离级别 描述的 可重复读) 。
也就是 innodb 读不加锁 。但是写加了锁,在什么时候加锁呢? 在我们执行一条 update 语句的时候 。在什么时候释放锁呢? 在事务提交的时候 。
 
时间事务a 开始 事务b 开始
t11 随便 读点啥..... 1 随便 搞点啥
t22 update 资源 1 锁 资源1,如果拿不到就等待 2 update 资源2 锁定资源2,锁不到就等待
t33 随便搞搞点 啥3 随便搞点啥
t44 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 秒 。

数据库的死锁原因 和 处理办法

文章插图




    推荐阅读