来自 澳门威尼斯人注册网站 2020-03-23 10:25 的文章
当前位置: 澳门威尼斯人平台 > 澳门威尼斯人注册网站 > 正文

mssqlserver数据导出到另外一个数据库

文章分享一篇关于减少mssqlserver数据库死锁的技巧,有需要了解的朋友可以参考一下。

摘自

mssqlserver数据导出到另外一个数据库

这里的办法,对所有的数据库都适用。

死锁(Deadlock)

1. 找到想要导出的数据库,右键选择"任务"再选择"导出数据"

澳门威尼斯人注册网站 1

澳门威尼斯人注册网站 2

 

这个解决办法步骤如下:

所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁。 一种情形,此时执行程序中两个或多个线程发生永久堵塞(等待),每个线程都在等待被其他线程占用并堵塞了的资源。例如,如果线程A锁住了记录1并等待记录2,而线程B锁住了记录2并等待记录1,这样两个线程就发生了死锁现象。计算机系统中,如果系统的资源分配策略不当,更常见的可能是程序员写的程序有错误等,则会导致进程因竞争资源不当而产生死锁的现象。锁有多种实现方式,比如意向锁,共享-排他锁,锁表,树形协议,时间戳协议等等。锁还有多种粒度,比如可以在表上加锁,也可以在记录上加锁。(回滚一个,让另一个进程顺利进行)

1. 设置数据源

澳门威尼斯人注册网站 3

 

  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.

产生死锁的原因主要是:

3.设置导出到的数据库信息

澳门威尼斯人注册网站 4

 

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 .);}

(1)系统资源不足。

1. 设置要复制的数据

这里有两大类,一是直接复制某些表,二是根据sql查询出的指定数据

澳门威尼斯人注册网站 5

 

复制某些表的话选择第一项,之后选择要复制的表,选择之后点击"完成"按钮即可开始复制数据从源数据库到目标数据库

澳门威尼斯人注册网站 6

 

选择第二个的话,需要提供sql以获取复制的数据集

澳门威尼斯人注册网站 7

  1. 更新一行数据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 .);}

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

(2) 进程运行推进的顺序不合适。

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

(3)资源分配不当等。

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 管理数据库事务。

(1) 互斥条件:一个资源每次只能被一个进程使用。

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

(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

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

破解:静态分配(分配全部资源)

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

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

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

(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

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

破解:可剥夺

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

(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

本文由澳门威尼斯人平台发布于澳门威尼斯人注册网站,转载请注明出处:mssqlserver数据导出到另外一个数据库

关键词: