SELECT * FROM transaction_test;
id name age
2 lisi 17
2 lisi 17
1 zhangsan 20
开启一个事务A,执行更新操作,不提交,也不回滚。
BEGIN;
UPDATE transaction_test SET name = 'UPDATE TEST' WHERE id = 2;
执行结果:
BEGIN
> OK
> Time: 0s
UPDATE transaction_test SET name = 'UPDATE TEST' WHERE id = 2
> Affected rows: 2
> Time: 0.002s
开启一个事务B,执行更新操作,注意要修改同一条数据,并且事务A未提交,未回滚。
BEGIN;
UPDATE transaction_test SET name = 'UPDATE TEST' WHERE id = 2;
执行结果:
BEGIN
> OK
> Time: 0s
注意:此时事务B的更新操作并没有信息反馈,说明事务B被阻塞了。
在事务A中执行回滚操作。
ROLLBACK;
原本被阻塞的事务B立马又信息反馈:
UPDATE transaction_test SET name = 'UPDATE TEST' WHERE id = 2
> Affected rows: 2
> Time: 165.815s
所以第一个事务回滚,那么它的作用将被忽略,第二个事务将继续执行它的操作。
```
如果两个事务修改的不是同样的数据会怎么样???
执行过程同上面讲到的。
但是结果却不一样:
事务A:
BEGIN;
UPDATE transaction_test SET name = 'UPDATE TEST' WHERE id = 1;
BEGIN
> OK
> Time: 0s
UPDATE transaction_test SET name = 'UPDATE TEST' WHERE id = 1
> Affected rows: 1
> Time: 0s
事务B:
BEGIN;
UPDATE transaction_test SET name = 'UPDATE TEST' WHERE id = 2;
BEGIN
> OK
> Time: 0s
UPDATE transaction_test SET name = 'UPDATE TEST' WHERE id = 2
> Affected rows: 2
> Time: 0.001s
事务A不会阻塞事务B.
```
DELETE 操作
开启一个事务A:执行删除操作,不提交也不回滚。
BEGIN;
DELETE FROM transaction_test WHERE id = 2;
BEGIN
> OK
> Time: 0.001s
DELETE FROM transaction_test WHERE id = 2
> Affected rows: 2
> Time: 0.001s
开启事务B:执行删除操作,注意上次同样条件的数据,事务A保持不提交,不回滚。
BEGIN;
DELETE FROM transaction_test WHERE id = 2;
BEGIN
> OK
> Time: 0.001s
注意:此时事务B的删除操作并没有信息反馈,说明事务B被阻塞了。
在事务A中执行回滚操作:
ROLLBACK;
事务B中立刻又信息反馈:
DELETE FROM transaction_test WHERE id = 2
> Affected rows: 2
> Time: 78.159s
```
两个并发事务删除不同的数据:
结果是开始执行的事务不会阻塞后面的事务。
```
UPDATE DELETE 同上。
阻塞事务提交
删除提交
开启一个事务A:执行删除操作,但先不提交。
BEGIN;
DELETE FROM transaction_test WHERE id = 2;
执行结果:
BEGIN
> OK
> Time: 0s
DELETE FROM transaction_test WHERE id = 2
> Affected rows: 2
> Time: 0.001s
开启事务B,执行相同数据更新操作。
BEGIN;
UPDATE transaction_test SET name = 'UPDATE TEST' WHERE id = 2;
执行结果:
BEGIN
> OK
> Time: 0.002s
事务B被阻塞。
此时提交A事务。
COMMIT;
B事务返回信息:
UPDATE transaction_test SET name = 'UPDATE TEST' WHERE id = 2
> Affected rows: 0
> Time: 87.423s
如果事务B执行的是删除同样的数据。同修改一样。
结论:如果第一个事务进行删除提交,那么第二个事务将忽略该行。
如果第一个事务影响的数据和第二个事务影响的数据不同,则不会阻塞。
只有两个事务影响的数据有交叉才会阻塞,并按照结论。
更新提交
第一个事务更新后数据依然满足事务2的查询条件。
SELECT * FROM transaction_test;
id name age
1 zhangsan 17
1 zhangsan 17
1 zhangsan 17
2 zhangsan 17
开启一个事务A:进行更新操作,先不提交。
BEGIN;
UPDATE transaction_test SET name = 'UPDATE TEST - transaction 1' WHERE id = 2;
执行结果:
BEGIN
> OK
> Time: 0.001s
UPDATE transaction_test SET name = 'UPDATE TEST - transaction 1' WHERE id = 2
> Affected rows: 1
> Time: 0.001s
开启事务B,执行对相同数据的修改操作:
BEGIN;
UPDATE transaction_test SET name = 'UPDATE TEST - transaction 2' WHERE id = 2;
执行结果:
BEGIN
> OK
> Time: 0s
事务B被阻塞。
这个时候提交事务A。
表中的数据如下:
id name age
1 zhangsan 17
1 zhangsan 17
1 zhangsan 17
2 UPDATE TEST - transaction 1 17
此时事务B信息反馈:
UPDATE transaction_test SET name = 'UPDATE TEST - transaction 2' WHERE id = 2
> Affected rows: 1
> Time: 69.413s
提交事务B,表中的数据:
id name age
1 zhangsan 17
1 zhangsan 17
1 zhangsan 17
2 UPDATE TEST - transaction 2 17
第一个事务更新后数据原来不满足的记录满足事务2的查询条件。
开启事务A:不提交
BEGIN;
UPDATE transaction_test SET id = 2 WHERE name = 'zhangsan';
BEGIN
> OK
> Time: 0.001s
UPDATE transaction_test SET id = 2 WHERE name = 'zhangsan'
> Affected rows: 4
> Time: 0.003s
开启事务B,此时事务A并没有提交。
BEGIN;
UPDATE transaction_test set name='wangwu' WHERE id = 2;
BEGIN
> OK
> Time: 0.001s
事务B被阻塞,此时提交A,B返回信息:
UPDATE transaction_test set name='wangwu' WHERE id = 2
> Affected rows: 1
> Time: 94.131s
提交B,受影响的只有一行,即最初发现的行。原本不满足事务B修改操作条件的,即使经过事务A满足了事务B修改操作的条件,也不会被修改。
第一个事务更新提交后数据不再满足事务2的条件。
表中数据
id name age
2 AAA 17
1 zhangsan 17
1 zhangsan 17
1 zhangsan 17
开启事务A:修改操作,不提交。
BEGIN;
UPDATE transaction_test SET id = 1 WHERE name = 'zhangsan';
BEGIN
> OK
> Time: 0s
UPDATE transaction_test SET id = 1 WHERE name = 'zhangsan'
> Affected rows: 4
> Time: 0s
开启事务B:修改id=2的记录。
BEGIN;
DELETE FROM transaction_test WHERE id = 2;
BEGIN
> OK
> Time: 0.001s
事务B被阻塞,这是提交A,事务B返回信息。
DELETE FROM transaction_test WHERE id = 2
> Affected rows: 0
> Time: 108.07s
修改操作同上。