MySQL 事务处理级别不严格
以前在做软件开发时(我使用的是 Java 进行软件开发),数据库一直用 MySQL。但是一直没有使用 MySQL 的事务处理。
这两天学习了一下。不过,MySQL 的事务处理级别,似乎并不严格。
Java 中有这么几种事务级别:
1: TRANSACTION_READ_UNCOMMITTED 在这个事务级别下,可以发生脏度,不可重读,虚读
2: TRANSACTION_READ_COMMITTED 在这个事务界别下,不能发生脏度,但允许不可重读和虚读
3: TRANSACTION_REPEATABLE_READ 在这个事务界别下,不能发生脏度,和不可重读,但可以存在虚读
4: TRANSACTION_SERIALIZABLE 最高的事务级别,脏度,不可重读,虚读 都不能发生。
UNCOMMITTED ,COMMITTED 和 SERIALIZABLE 都没有问题。
但是在 TRANSACTION_REPEATABLE_READ 这个事务级别下,就有一点让人不解。MySQL 对于这个事务级别的处理是“脏度,不可重读,和虚读都不会发生”
以下是我对这个事务级别的测试逻辑:
1:与 MySQL 建立 Connection_1 采用 TRANSACTION_REPEATABLE_READ 事务级别
与 MySQL 建立 Connection_2 同样采用 TRANSACTION_REPEATABLE_READ 事务级别
2:Connection_1 执行 SELECT * FROM atable 得到一个结果集
3: Connection_2 执行 INSERT INTO atable ... 想 atable 中添加一条数据
Connection_2 执行 commit
4: Connection_1 再次执行 SELECT * FROM atable 此时,得到的结果集,与之前得到的完全一致,可见没有发生“虚读”
从上面的结论,我认为 MySQL 并不区分不可重读和虚读。但是如果真是这样,TRANSACTION_REPEATABLE_READ 就可以防止虚读,那 MySQL 最好级别的事务用来做什么呢(测试中,能够看出,如果启用了 MySQL 最高级别的事务处理,则这些事务与其它事务的确是串行执行)。