隔离级别:
分为:
1.读未提交;2.读已提交;3.可重复读;4.串行划
数据库会出现的问题:1.脏读;2.不可重复读;3.幻读
不同隔离级别,能处理的问题不同:
那来看看下面一些概念:
脏读:指的是一个事务读取到了另一个事务未提交的更新数据:
===session1=== SELECT @@tx_isolation; SET tx_isolation='READ-UNCOMMITTED'; BEGIN; insert into students(`name`,age,teacherId) VALUES ('takey123',25,1) ROLLBACK; COMMIT; ===session2=== SET tx_isolation='READ-UNCOMMITTED'; SELECT * FROM students
说明:事务1,设置隔离级别为读未提交。然后开启事务,insert一条记录,但是不提交。
此时事务2,查询到了所有数据,包扣事务1插入但是还没提交的数据,假如做了sum()运算。这是事务1回滚事务。这样就出问题了。事务2的数据并不是准确的。
为了避免这种情况,只能设置更高的隔离级别
不可重复读:一个事务多次读取同一数据返回的结果不同,换句话说,后续读取可以读到另一个事务已提交的更新数据。
相反, “可重复读”在同一事务中多次读取数据时, 能够保证所读数据一样, 也就是后续读取不能读到另一事务已提交的更新数据。
事务B修改数据导致当前事务A前后读取数据不一致 ,侧重点在于事务B的修改
===session1=== SELECT @@tx_isolation; SET tx_isolation='READ-COMMITTED'; BEGIN; SELECT * FROM students SELECT * FROM students COMMIT; ===session2=== SET tx_isolation='READ-COMMITTED'; UPDATE students SET age=25 WHERE `name`='min';
说明:事务1第一次读取数据表,获取学生的年龄是25岁。此时事务2对该学生的年龄修改为40并提交。
事务1第二次读取数据表,获取学生的年龄是40岁。这就出现了同一事务多次读取到的数据不一致,导致不可重复读。
幻读:查询表中数据如果没有存在就插入一条数据。在并发的时候,里面会出现2条一样的数据。
事务A在查询数据库是,发现没有此数据,就去插入一条数据,但是此时事务B也是查询不到数据去插入一条数据并插入成功了。
如果事务A此时再去查的时候,发现了有这条数据,就感觉出现了幻觉,明明自己还没插入,但是又出现了这条数据。
===session1=== SELECT @@tx_isolation; SET tx_isolation='REPEATABLE-READ'; BEGIN; SELECT * from students WHERE `name`='takey123'; #此时,另一个事务插入了数据 SELECT * from students WHERE `name`='takey123'; insert into students(`name`,age,teacherId) VALUES ('takey123',25,1) SELECT * from students WHERE `name`='takey123'; UPDATE students SET age=40 WHERE `name`='takey123'; SELECT * from students WHERE `name`='takey123'; COMMIT; ===session2=== SET tx_isolation='REPEATABLE-READ'; insert into students(`name`,age,teacherId) VALUES ('takey123',25,1)
说明:事务1,插入数据库中是否存在数据,如果不存在的时候去插入这条数据,但是在查询不存在的时候,事务2,插入了该条数据,
事务1也插入该条数据,导致数据库中有2条一模一样的数据。这就产生了幻读。
事务在什么时候不起作用呢:
1.bean是否是代理对象,如果不是代理对象,就不起作用。
2.入口函数是否是public的。