隔离MSSQL bcp加载到临时表中

时间:2010-08-14 15:18:37

标签: sql-server ado

我想清空一个临时表,通过bcp加载它,然后在移动到生产表之前修改它的行。命令看起来像这样:

  1. 截断表temp1
  2. bcp db.schema1.temp1 in import1.txt -h“TABLOCK”
  3. exec sp_modify_temp1_rows_move_to_production_table
  4. 我的问题是如何将所有这些作为一个事务执行,不一定是为了回滚它,而是为了提供隔离。

    这是想象的场景。 User1去加载import1.txt(这样做的实现细节,步骤1-3,对用户是隐藏的)。在第2步完成User1之前,User2启动自己的导入。锁定机制可防止其导入立即启动。主要关注的是User2的第1步将在User2的第2步完成后立即开始,从而在User1的第3步之前清除该表,并且该过程可以完成。

    另外三个注释:

    1. 客户端通过ADO执行(不要误用ADO.NET)
    2. BULK INSERT不是一个选项
    3. 首选通过ADO扩展一些锁定机制,包括步骤2和流程的步骤1 - 如果可能的话 - 知道这也是不可能有帮助的。

2 个答案:

答案 0 :(得分:3)

典型的解决方案是使用通过

获取的applocks
sp_getapplock 'importing-ABC', 'Exclusive', 'Session';

这样您就可以锁定逻辑资源(任意字符串/名称),并且按照惯例,尝试执行相同操作的其他用户必须尝试获取相同的 applock。在保持applock的同时,bcp命令可以无干扰地运行。请注意,会阻止其他用户/应用程序不遵守协议(因为无知,恶意或愚蠢)。

答案 1 :(得分:1)

1)第一个解决方案

  • 将SessionId字段添加到temp1表
  • 添加load_session_state表PK sessionId,状态tinyint(处理步骤1,处理步骤2 ...完成...)
  • sp_modify_temp1_rows_move_to_production_table将仅执行一些sessionId和State = Done的记录。 (sp_modify_temp1_rows_move_to_production_table可以使用sql代理程序作业异步执行)
  • truncate应替换为DELETE WHERE SessionId =(它很慢,但必须这样做)。 (它可以由相同的sql代理作业执行,但在将记录移动到生产之后)
  • 应从bcp命令
  • 中删除TABLOCK

2)第二种解决方案

  • 创建表 temp_XXX
  • import1.txt -h“TABLOCK”中的
  • bcp db.schema1。 temp_XXX
  • exec sp_modify_tempXXX_rows_move_to_production_table     @table_name ='temp_XXX'(使用带有@table_name参数的动态sql)
  • DROP TABLE temp_XXX

<强> ADDED

3)使用表load_session_state作为进度视图并锁定您的进程。如果其中有任何记录,请通知用户等待。使用您之前的解决方案,无需更只需使用table load_session_state作为逻辑锁