数据库死锁的解决办法

转载 2012年03月21日 14:18:16

这个解决办法步骤如下:

1. 每个表中加 updated_count (integer) 字段

 

2. 新增一行数据,updated_count =0 :
insert into table_x (f1,f2,...,update_count) values(...,0);

 

3. 根据主键获取一行数据 SQL,封装成一个 DAO 函数(我的习惯是每个表一个 uuid 字段做主键。从不用组合主键,组合主键在多表 join 时 SQL 写起来很麻烦;也不用用户录入的业务数据做主键,因为凡是用户录入的数据都可能错误,然后要更改,不适合做主键)。
select * from table_x where pk = ?

 

4. 删除一行数据
4.1 先通过主键获取此行数据, 见 3.

4.2 delete from table_x where pk = ? and update_count=? , 这里 where 中的 update_count 通过 4.1 中获取
4.3 检查 4.2 执行影响数据行数,如果删除失败,则是别人已经删除或者更新过同一行数据,抛异常,在最外面 rollback,并通过合适的词语提醒用户有并发操作,请稍候再试。
int count = cmd.ExecuteNonQuery();
if(udpatedCount < 1){
throw new Exception(“检测到并发操作,为防止死锁,已放弃当前操作,请稍候再试,表 xxx, 数据 key ….”);
}

 

5. 更新一行数据
5.1 先通过主键获取此行数据, 见 3.
5.2 update table_x set f1=?,f2=?, ...,update_count=update_count+1 where pk = ? and update_count=? , 这里where 中的 update_count 通过 5.1 中获取
5.3 检查 5.2 执行影响数据行数,如果更新失败,则是别人已经删除或者更新过同一行数据,抛异常,在最外面 rollback,并通过合适的词语提醒用户有并发操作,请稍候再试。
int count = cmd.ExecuteNonQuery();
if(udpatedCount < 1){
throw new Exception(“检测到并发操作,为防止死锁,已放弃当前操作,请稍候再试,表 xxx, 数据 key ….”);
}

 

6. 数据库访问层 DAO 中,绝对不要写 try catch,也不要写 commit/rollback. 因为当我写了一个 dao1.insert(xxx) ,另一个人写了 dao2.insert(xxx), 两周后有可能会有人把这两个函数组合在一起放在一个事务中。如果dao1.insert(xxx)已经 commit ,那么dao2.insert(xxx) 中rollback 会达不到期望效果。很多电脑书中示例代码,都有这个错误。


数据库事务应该是这样界定起始范围:

6.1 单机版程序,每个按钮操作,对应一个事务。可以在把 connection/transaction 传递到 dao 中。在按钮响应的代码处,处理事务。catch 到任何 Exception 都要 rollback.


6.2 网页版程序,每个按钮操作,对应一个事务。可以在把 connection/transaction 传递到 dao 中。在按钮响应的代码处,处理事务。我强烈建议对于 Web应用,数据库连接的打开/关闭、数据库事务的开始和 commit/rollback 全在 filter 中处理(Java EE 和 ASP.NET MVC 都有 filter, 其它的不知道),事务、数据库连接通过 threadlocal 传入到 DAO 中。filter 中 catch 到任何 Exception 都要 rollback.

 

见过很多用 Spring 的人,代码中启动了几个数据库事务自己都不知道,符不符合自己的需要,也不知道。我的建议是,禁止使用 Spring 管理数据库事务。

 

7. 单表的增、删、改、通过主键查,应该用工具自动生成。自动生成代码,应该放在单独一个目录,以便后面有数据库表改动,可以重新生成代码并覆盖。自动生成的文件,在第一行就写上注释,表示这是一个自动生成的文件,以后会被自动覆盖,所以不要改这个文件。

举例来说,对于 tm_system_user 表,可以自动生成 TmSystemUserDAO, 包含函数: insert(TmSystemUser), update(TmSystemUser), delete(TmSystemUser), getByKey(key), batchInsert(TmSystemUser[])。


8. 总是使用事务,并用 ReadCommited 级别,即使是纯查询 SQL,也这么写。这可以简化设计与写代码,没有发现明显多余的性能消耗。

 

9. 数据设计时,尽量避免 update/delete. 举例来说,如果是一个请假条的审批流程,把请假条申请设计成一个表,领导批复设计成另一个表。尽量避免设计时合并成一个表,把批准状态(同意/否决)、批准时间当成“请假条申请”的属性。
说极端一点,最好从数据库设计上,避免后续编程有 update/delete, 只有 insert。 好像现在流行的 NoSQL 也是这么个思路。

 

10. 补充,如果在后台检查页面录入数据,报错处理,有以下两种方法:

10.1 只要有一个错误,就 throw exception.

10.2 把所有的错误都检测出来,比如,用户名未录入,电子邮件未录入,放在一个 List中,然后 throw exception.

http://www.cnblogs.com/jacklondon/archive/2012/03/21/2409666.html

数据库死锁解决方案

一、活锁 如果事务T1封锁了数据R,事务T2又请求封锁R,于是T2等待。T3也请求封锁R,当T1释放了R上的封锁之后系统首先批准了T3的请求,T2仍然等待。然后T4又请求封锁R,当T3释放了R上的封锁...
  • zkn_CS_DN_2013
  • zkn_CS_DN_2013
  • 2015年11月19日 15:49
  • 972

oracle数据库死锁解决方法

在做项目中,在程序完全正确的情况下,出现了当执行sql语句的时候停止工作的现象,开始是怀疑出现了死锁,当利用sql查询时发现自己是对的,死锁通常都是我们应用程序设计不合理造成的,如何处理数据库中的死锁...
  • suneqing
  • suneqing
  • 2015年04月29日 20:03
  • 2441

oracle死锁解决常用方法(屡试不爽)

--1.查询被锁的情况 select object_name,machine,s.sid,s.serial# from v$locked_object l,dba_objects o ,v...
  • goodhuajun
  • goodhuajun
  • 2014年09月30日 15:18
  • 3054

数据库常见死锁原因及处理

数据库和操作系统一样,是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。...
  • qq_16681169
  • qq_16681169
  • 2017年07月08日 10:22
  • 4784

c3p0数据库连接池死锁问题

c3p0数据库连接池死锁问题 项目进行压力测试的时候,运行大概1小时候,后台抛出以下异常: Nov 9, 2012 1:41:59 AM com.mchange.v2.as...
  • killerover84
  • killerover84
  • 2015年09月23日 09:15
  • 1415

数据库 活锁和死锁

一、活锁 如果事务T1封锁了数据R,事务T2又请求封锁R,于是T2等待。T3也请求封锁R,当T1释放了R上的封锁之后系统首先批准了T3的请求,T2仍然等待。然后T4又请求封锁R,当T3释放了R上...
  • sunmenggmail
  • sunmenggmail
  • 2012年09月23日 20:58
  • 3923

数据库技术之死锁的实例和监测

背景介绍:学习就是一个在原有基础上不断提高的过程,在耿建玲老师视频的学习之后,我们缺少了最重要的一步就是实际操作,有些东西看似很简单,但是真正做的时候,就会遇到了困难。写这篇博客的目的就是在原来的基础...
  • lwt976647637
  • lwt976647637
  • 2015年08月23日 17:04
  • 930

数据库死锁分析与解决

一、死锁的表现1、错误信息是:事务(进程 ID)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。2、错误信息是:事务(进程 ID )与另一个进程被死锁在 锁 | 通信缓冲区...
  • hexieshangwang
  • hexieshangwang
  • 2015年09月07日 11:59
  • 412469

数据库死锁原因及解决办法

死锁(Deadlock)   所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死...
  • LemonTreey
  • LemonTreey
  • 2016年11月07日 16:31
  • 11842

数据库中死锁那些事儿

说起数据中的死锁,已经多次在笔试题目中遇到。今天特此做一个数据库死锁方面的总结,以绝后患,吼吼! 一、首先我们来看几个定义: 1.死锁 所谓死锁: 是指两个或两个以上的进程在执行过程中,...
  • qitian0008
  • qitian0008
  • 2012年07月27日 20:17
  • 15690
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据库死锁的解决办法
举报原因:
原因补充:

(最多只允许输入30个字)