我有一个需要执行的命令列表,所有这些命令都包含在我命名为 的表中myQueue。这个表有点独特,因为一些命令应该组合在一起,以便它们的执行按顺序执行,而不是并发执行,因为同时执行它们会导致不需要的数据工件和错误。因此,队列不能以典型的FIFO / LIFO方式分类,因为出队顺序是在运行时确定的。
总结一下:
myQueue将充当命令队列(其中出队顺序在运行时确定)UPDATE而不是 a执行的,DELETE因为此表用于所述命令的历史性能报告我目前的方法是通过sp_getapplock/sp_releaseapplock调用使用显式互斥逻辑来迭代这个表。虽然这按预期工作,但该方法会生成足够的锁定,因此在任何给定时间都无法在队列上迭代大量工作线程。在阅读了 Remus Rusanu关于该主题的优秀博客文章后,我决定尝试使用表格提示,希望可以进一步优化我的方法。
我将包含下面的测试代码,但总结一下我的结果,使用表提示和消除对sp_getapplock/ 的调用的缺点sp_releaseapplock最多会导致以下三种不良行为:
不过,从积极的方面来说,当代码适应死锁时(例如,重试当前包含的违规操作),不使用sp_getapplock/sp_releaseapplock且不会表现出不良行为的方法 2 和 3 的执行速度至少是两倍,如果不是更快的话.
我希望有人会指出我没有正确构建出列语句,这样我仍然可以继续使用表提示。 如果那不起作用,那就这样吧,但我想看看它是否可以做到同样的事情。
可以使用以下代码设置测试。
该myQueue表的创建和人口与命令类似于够我的工作量:
CREATE TABLE myQueue
(
ID INT IDENTITY (1,1) PRIMARY KEY CLUSTERED,
Main INT, …Run Code Online (Sandbox Code Playgroud) 运行 SQL Server 2008;Mgmt Studio 2008。我正在处理我们为 MS CRM 4.0 实施创建的 MS SQL 作业。对于熟悉 CRM 的任何人来说,这项工作每晚清除 aSyncOperationBase 表以节省数据库大小。这是工作代码:
Begin Transaction T1
Declare @p30Days as DateTime
Declare @p3Years as DateTime
Set @p30Days = DateAdd(d, -30, GetDate())
Set @p3Years = DateAdd(d, -1095, GetDate())
update AsyncOperationBase
set deletionstatecode=2
where deletionstatecode = 0 and
statecode = 3 and
completedon is not null and
completedon < @p30Days
and OperationType <> 10
update AsyncOperationBase
set deletionstatecode=2
where deletionstatecode = 0 and
statecode = 3 and
completedon is …Run Code Online (Sandbox Code Playgroud) 隔离级别为 REPEATABLE_READ。
逻辑如下:
Transaction begins
Read data from Table A
If (Table A has Any Data) End Transaction and exit
If Table A has No Data, Proceed further
Delete a record in Table B
Transaction ends
Run Code Online (Sandbox Code Playgroud)
现在,我的问题是关于以下场景:
事务中是否有任何隐式锁定,或者我是否需要明确锁定表 A 以便在我提交更改之前没有人可以在表 A 中插入任何数据?
在 InnoDB 上运行 Mysql 5.1.57,并且存在数据库锁定问题。
我有两个单独的会话连接到单个数据库 MySQL。在第一个会话中,我在表 A 上运行了一个很长的 SELECT 查询(技术上是一个慢速查询)。然后在另一个连接上,我在表 B 上运行了一个小的 UPDATE 查询。
编辑:如本主题底部所述,当表/查询完全位于不同的数据库中时也会出现此问题,并且不限于表/查询位于同一数据库中。
由于某种原因,在长选择查询完成之前,表 B 上的更新不会完成,就好像它们在同一个连接上一样。此外,“PROCESS LIST”将第二个查询显示为“正在释放项目”,同时它正在等待执行。
是否有任何设置或配置问题会导致这些查询按顺序运行而不是同时运行?
在此先感谢您的帮助。
表A
CREATE TABLE `history` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`log` text NOT NULL,
`created_at` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id_idx` (`user_id`),
CONSTRAINT `history_user_id_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=364398 DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)
表B
CREATE TABLE `client` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`root_id` int(11) DEFAULT …Run Code Online (Sandbox Code Playgroud) 根据隔离级别,可能会展示 SELECTS 不同行为的场景:
1) 0:00 Thread A runs a query that returns 1000 rows that takes 5 minutes to complete
2) 0:02 Thread B runs a query that returns the same 1000 rows
3) 0:05 Thread A updates the last 1 rows in this result set and commits them
4) 0:07 Thread B's query returns*
Run Code Online (Sandbox Code Playgroud)
根据隔离级别,#4 中的结果集要么包含线程 A 的更改,要么不包含。UPDATES 也是如此吗?
下面是一个示例场景:
Thread A: UPDATE... set version=6 ... WHERE primary_key = 1234 AND version = 5
Thread B: UPDATE... set …Run Code Online (Sandbox Code Playgroud) 您好,为了学习,我试图故意使 SQL select 语句被另一个简单的 SQL 删除或更新语句阻塞。我只喜欢 InnoDB 表。
为了准备测试,我创建了一个表
CREATE TABLE `test`.`client` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
Run Code Online (Sandbox Code Playgroud)
并在表中插入了 1,000,000 行。
现在我要开始测试了。
在 MySQL 客户端 #1 中,我删除了所有行:
mysql #1> delete from client;
Run Code Online (Sandbox Code Playgroud)
当删除仍在执行时,在另一个 MySQL 客户端 #2 中,我尝试选择一行。
mysql #2> select * from client where id=1;
+---------+------+
| id | name |
+---------+------+
| 1 | joe |
+---------+------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
结果立即显示,选择没有被阻止。
接下来我将尝试另一个测试。我在表中插入了 1,000,000 行。
在 MySQL 客户端 …
有人可以解释一下进程如何获取SIX页面上的锁吗?在我的死锁图 xml 文件中,我看到在RC 隔离级别下运行的进程(在死锁时刻执行 select 语句)持有SIX页面上的锁。
这是什么意思以及如何获得该锁?从我从http://msdn.microsoft.com/en-us/library/aa213039%28v=sql.80%29.aspx 获得的信息中,SIX锁保护S所有资源IX上的-locks,并锁定层次结构中较低的一些资源。
对于我的情况,那将是IX行上的锁?可以IX-Lock放在一排?(我觉得不是)。我很迷惑。
另一件事是,我希望X行上有几个-locks 而根本没有S-locks(因为IL是ReadCommited)。SIX如果我只在前面的语句中插入了几条记录,为什么我锁定了整个页面?
编辑:死锁xml:
<deadlock-list>
<deadlock victim="process4df94c8">
<process-list>
<process id="process4df94c8" taskpriority="0" logused="2968" waitresource="PAGE: 7:1:181357" waittime="3111" ownerId="41854656297" transactionname="user_transaction" lasttranstarted="2013-06-06T11:09:42.087" XDES="0x1d2434e80" lockMode="IX" schedulerid="6" kpid="3476" status="suspended" spid="52" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2013-06-06T11:09:42.183" lastbatchcompleted="2013-06-06T11:09:42.183" clientapp=".Net SqlClient Data Provider" hostname="CWCEINAW" hostpid="4260" loginname="cwcuser" isolationlevel="read committed (2)" xactid="41854656297" currentdb="7" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056"> …Run Code Online (Sandbox Code Playgroud) 如果在具有“读取已提交快照”隔离级别的表上运行更新并且提交未决
例如:
update table1 set col1 = col1 + 1 where PKcol < 3update table1 set col1 = col1 + 1 where PKcol = 3update table1 set col1 = col1 + 1 where NonPKcol < 3update table1 set col1 = col1 + 1 where NonPKcol = 3update table1 set col1 = col1 + 1 where PKcol < 3 and NonPKcol = 5在上述情况下,PKcol 是表中的主键,而 NonPKcol 是非主键。
是否只为满足“where”条件的行锁定更新?它是基于值、索引还是主列?
在 SQL Server 2008 中,我有视图WITH SCHEMABINDING,我需要更改一个视图。
我正在更改列而不更改其别名,因此消费者不会受到影响。
如果我要删除所有其他依赖于此的视图,我将能够再次重新创建它们,因此SCHEMABINDING仍然有效。
我可以暂时禁用此视图上的架构锁ALTER吗?
或者我必须删除依赖视图并在更改后重新创建它们?
locking ×10
mysql ×4
sql-server ×4
innodb ×3
deadlock ×2
transaction ×2
amazon-rds ×1
blocking ×1
concurrency ×1
oracle ×1
postgresql ×1
queue ×1
schema ×1
select ×1
t-sql ×1
view ×1