并发丢弃的mysql事务没有锁

时间:2013-01-23 17:04:41

标签: mysql transactions locking

我目前正在尝试改进应用程序的测试行为。

测试当前在嵌套事务中启动,其中测试套件启动实际事务,测试用例每个都创建嵌套保存点。

完成测试用例后,将简单地释放保存点并恢复原始数据。 套件完成后,将回滚事务。

(在表上使用截断对我们来说不是一个选项,因为种子数据只是大而且它会阻止中心和并发测试)

这很好用。

当事务并发运行时,事务往往会相互锁定表。对于具有唯一键的表(在两个事务中的一个中,每个测试都失败),情况更是如此。

我尝试使用事务状态“READ COMMITTED”,“READ UNCOMMITED”和默认的“REPEATABLE READ”来执行此操作。

READ UNCOMMITTED导致重复的关键问题。 READ COMMITTED有锁/死锁问题 REPEATABLE READ有锁定/死锁问题(与上面相同)

此外,我尝试应用以下选项:     innodb_autoinc_lock_mode = 2

> -- mysql command line
> SET SESSION binlog_format=ROW
> SET SESSION innodb_table_locks=OFF

最后一个参数解决了一些锁定问题。 “锁定等待超时”和死锁问题仍然存在。

是否有解决方案使单独的交易真正相互独立?

更新:进一步测试显示: 死锁当前仅发生在具有唯一键的表上。 我认为会话1已经使用了这些密钥,所以我可能是行锁定的受害者。

mysql服务器版本:5.5.15

编辑:添加工作流示例,因此问题更明确,(可能包含拼写错误和次要语法错误。这些不是重点)。不同的联系意图不同

> create table foo (
>   `id` int(11) auto increment,
>   `name` varchar(255),
>   PRIMARY KEY id,
>   UNIQUE KEY `name`(`name`)
> ) ENGINE=InnoDb;
> insert into foo(name) values ('bar');

> begin;                                       -- connection 1, transaction 1
>   begin;                                     -- connection 2, transaction 1
> savepoint t_1;                               -- connection 1, savepoint within transaction 1
>   savepoint t_1;                             -- connection 2, savepoint within transaction 1
> select count(*) from foo;                    -- connection 1, number of entries in foo, should be 1
> insert into foo('name') values ('meh');      -- connection 1, insert into foo the unique fixed value 'meh', should work
>   select count(*) from foo;                  -- connection 2, number of entries in foo, should be 1
>   insert into foo('name') values ('meh');    -- connection 2, insert into foo the unique fixed value 'meh', should work
> select count(*) from foo;                    -- connection 1, number of entries in foo, should be 2
>   select count(*) from foo;                  -- connection 2, number of entries in foo, should be 2
> rollback to savepoint t_1;                       -- connection 1, discard everything up until savepoint t_1
> rollback;                                    -- connection 1, rollback
>   rollback to savepoint t_1;                     -- connection 2, discard everything up until savepoint t_1
>   rollback;                                  -- connection 2, rollback

在此示例中,所有应被视为我想要的事务隔离的测试。

1 个答案:

答案 0 :(得分:0)

听起来你正试图同时在彼此的顶部运行测试,这就是为什么会出现并发查询的原因。如果是这种情况,那么我认为你是100%正确的,因为你只是在经历锁定。

如果存在一个打开的事务(即一个长时间运行的测试),当测试结束时,预期的目的是回滚,那么在进行任何其他写入时可能会遇到很多麻烦,并且可能会对这些行进行一些读取操作/ tables作为其他测试的一部分。你最好的选择就是按顺序运行所有东西。

您遇到的重复键问题与使用READ UNCOMMITTED时的预期一致。

相关问题