首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >数据库隔离模型

数据库隔离模型
EN

Stack Overflow用户
提问于 2012-11-16 06:20:47
回答 3查看 123关注 0票数 2

我有一个带有"ID“列的数据库。每当有数据库的新条目时,我从数据库中获取最后一个ID,增加值,然后在Insert语句中使用它。

编辑:我需要在多个Insert语句中使用ID。我将从主表中获取此ID,并使用该ID将值插入相关表中。

代码语言:javascript
运行
复制
    NextID = Select Max(ID) + 1 From Table

    INSERT INTO Table1(ID, Col1, Col2...) Values(NextId, Value1, Value2...)

    INSERT INTO Table2 (ID,col1,col2....) Values (NextID, Value1, Value2...)

我不知道这是否是一个好方法,因为我知道会有并发问题。当我的应用程序试图读取NextID时,应用程序的另一个实例也可能试图读取相同的值,因此可能会出现并发问题。

是否有适当的方法来处理这种情况?我的意思是,有一些方法可以设置数据库隔离级别。在这种情况下,这将是一个适当的隔离级别。

另外,如果有人可以建议我使用另一种方法来手动维护和增加数据库中的ID,我也会接受的。

如果这些信息还不够,请告诉我您需要什么。

我正在使用VB和2008使用ASP.Net。我不想使用Server的内置“标识”。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-11-16 09:38:21

获取下一个ID的唯一方法是实际插入行并使用标识。其他一切都会失败。因此,必须从插入父表开始

代码语言:javascript
运行
复制
begin transaction;
insert into Table (col1, col2, col3) values (value1, value2, value3);
set @Id = scope_identity();
insert into Table1(ID, col1, col2) values (@Id, ...);
insert into Table3(ID, col1, col2) values (@Id, ...);
commit;

这是原子和并发安全。

我不想使用Server的内置“标识”。

tl博士你“想要”的东西无关紧要,除非你能清楚地说明原因。你可以正确地做这件事,或者你可以花时间去重新发明轮子。

票数 3
EN

Stack Overflow用户

发布于 2012-11-16 07:12:24

显然,您有一个批处理的三个SQL语句-一个选择和两个插入。数据库引擎可以从它们之间的不同会话执行另一条语句,从而破坏您的数据一致性--其他一些会话可以获得与您已有的相同的MAX()值,并将其用于其他insert语句。阻止DB引擎执行此操作的唯一方法是使用事务。用BEGIN事务包装你的批次..。承诺你就完蛋了。

票数 1
EN

Stack Overflow用户

发布于 2012-11-16 07:35:38

你这样做很好,你需要的是事务处理。

代码语言:javascript
运行
复制
BEGIN TRANSACTION 

begin try
    NextID = Select Max(ID) + 1 From Table

    INSERT INTO Table1(ID, Col1, Col2...) Values(NextId, Value1, Value2...)

    INSERT INTO Table2 (ID,col1,col2....) Values (NextID, Value1, Value2...)

    COMMIT TRANSACTION 
end try

begin catch

    ROLLBACK TRANSACTION 
    --exception logging goes here

end catch
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13411474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档