SQL Server 插入论坛查询

发布于 2024-10-05 23:30:23 字数 641 浏览 3 评论 0原文

考虑到论坛表和许多用户同时向其中插入消息,此事务的安全性如何?

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION

 DECLARE @LastMessageId SMALLINT
 SELECT @LastMessageId = MAX(MessageId)
 FROM Discussions
 WHERE ForumId = @ForumId AND DiscussionId = @DiscussionId

 INSERT INTO Discussions
 (ForumId, DiscussionId, MessageId, ParentId, MessageSubject, MessageBody)
 VALUES
 (@ForumId, @DiscussionId, @LastMessageId + 1, @ParentId, @MessageSubject, @MessageBody)

IF @@ERROR = 0
BEGIN
 COMMIT TRANSACTION
 RETURN 0
END

ROLLBACK TRANSACTION
RETURN 1

在这里,我读取了最后一个 MessageId 并递增它。我无法使用身份字段,因为它需要为组中插入的每条消息递增(不是每条消息都插入表中)。

Considering a forum table and many users simultaneously inserting messages into it, how safe is this transaction?

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION

 DECLARE @LastMessageId SMALLINT
 SELECT @LastMessageId = MAX(MessageId)
 FROM Discussions
 WHERE ForumId = @ForumId AND DiscussionId = @DiscussionId

 INSERT INTO Discussions
 (ForumId, DiscussionId, MessageId, ParentId, MessageSubject, MessageBody)
 VALUES
 (@ForumId, @DiscussionId, @LastMessageId + 1, @ParentId, @MessageSubject, @MessageBody)

IF @@ERROR = 0
BEGIN
 COMMIT TRANSACTION
 RETURN 0
END

ROLLBACK TRANSACTION
RETURN 1

Here I read last MessageId and increment it. I can't use Identity field because it needs to be incremented for every message inserted in a group (not every message insert into table.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陪我终i 2024-10-12 23:30:23

您的事务确实应该非常安全 - 请查看 关于可串行化事务级别的 MSDN 文档< /a>:

可序列化

指定以下内容:

  • 语句无法读取已修改的数据但尚未修改
    由其他事务提交。

  • 没有其他事务可以修改已被读取的数据
    当前交易直到当前
    交易完成。

  • 其他事务无法插入具有以下键值的新行
    会落在读取的键范围内
    通过当前的任何语句
    交易直到当前
    交易完成。

范围锁被放置在与
每个语句的搜索条件
在事务中执行。这块
来自更新或的其他交易
插入任何符合条件的行
对于执行的任何语句
当前交易。这意味着
如果 a 中的任何语句
交易第二次执行
时间,他们会读同一组
行。范围锁定一直保持到
交易完成。这是
最严格的隔离
级别,因为它锁定整个范围
钥匙并持有锁直到
交易完成。因为
并发较低,使用此选项
仅在必要时。该选项有
与设置 HOLDLOCK 相同的效果
所有 SELECT 语句中的所有表
一笔交易。

此事务隔离级别的主要问题是,它对服务器造成相当大的负载,并且序列化(顾名思义)任何访问,因此您的服务器性能和可扩展性将受到影响,例如,如果用户数量非常多,您将用户等待事务完成时可能会出现大量超时。

因此,使用更轻量级的全局消息 id 方法作为INT IDENTITY 肯定要好得多!

Your transaction should be quite safe indeed - check out the MSDN docs on the SERIALIZABLE transaction level:

SERIALIZABLE

Specifies the following:

  • Statements cannot read data that has been modified but not yet
    committed by other transactions.

  • No other transactions can modify data that has been read by the
    current transaction until the current
    transaction completes.

  • Other transactions cannot insert new rows with key values that
    would fall in the range of keys read
    by any statements in the current
    transaction until the current
    transaction completes.

Range locks are placed in the range of key values that match the
search conditions of each statement
executed in a transaction. This blocks
other transactions from updating or
inserting any rows that would qualify
for any of the statements executed by
the current transaction. This means
that if any of the statements in a
transaction are executed a second
time, they will read the same set of
rows. The range locks are held until
the transaction completes. This is the
most restrictive of the isolation
levels because it locks entire ranges
of keys and holds the locks until the
transaction completes. Because
concurrency is lower, use this option
only when necessary. This option has
the same effect as setting HOLDLOCK on
all tables in all SELECT statements in
a transaction.

The main problem with this transaction isolation level is that it's a pretty heavy load on the server, and serializes (as the name implies) any access, so your server performance and scalability will suffer, e.g. with very high numbers of users, you'll possibly get lots of timeouts for users waiting for a transaction to finish.

So using the more lightweight approach of a global message id as INT IDENTITY is definitely much better!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文