0

我之前使用事务时遇到了一些问题。希望有人能帮我弄清楚。我会很感激任何帮助。谢谢你。

MySql表结构:

create table test (
    id int not null,
    someid int,
    name varchar(50),
    update_date datetime
);
primary key : id (auto-inc)
index1 : id (unique)
index2 : id, update_date (non-unique)

爪哇方法:

// consider this method is Transaction 1
method1() {
    A. set session transaction isolation level read commited;
    B. select update_date from test where someid = 1;
    C. insert into test values (some new data..);
    D. select update_date from test where someid = 1;
}

// consider this method is Transaction 2
methodb() {
    E. (start with default transaction isolation level - repeatable read)
    F. update test set udpate_date = now() where someid = 1;
}

这是我所做的:

  1. 在 D 处执行 method1() 和 break(在 eclipse 中设置断点)
  2. 并发执行method2()

请注意,“someid”不在索引中,但它存储的数据与“id”完全相同。

然后我什么都没有,只要我不提交事务1,或者最终它会以事务超时结束。但是,如果我将 where 子句更改为 id = 1 of F,则无需等待即可正常工作。在这里我很困惑,因为我没有锁定该表或任何行。如果我这样做了,就不应该这样做,对吧?

谁能告诉我为什么会这样?谢谢!

4

2 回答 2

1

条件 someId=1 要求数据库系统扫描全表,因为没有索引。insert 语句可能会插入 someid=1 的行,因此会影响第二个事务的结果。

当 id=1 时,dbs 可以确定只有一行受到语句 F 的影响。插入语句不会更改这一行。

我只是想知道,隔离级别是否会影响执行?

于 2012-02-05T07:46:21.227 回答
1

我不是 MySQL 并发控制方面的专家,但我猜你看到了锁定的效果:直到第一个事务提交,第二个事务不知道第一个事务插入的行是否会被提交,所以必须是停滞不前。

只有在第一个事务完成后,第二个事务才能继续,并且:

  • 更新行(如果第一个事务已提交)
  • 或不更新该行(如果第一个事务回滚,则该行实际上并未插入)。

问题是:为什么索引也没有发生id?您确定您对两次交易都使用了相同的价值someid吗?您是否更改了WHERE两笔交易的条款?

于 2012-02-05T08:25:55.433 回答