闲的无事,就像测试下spring的事务隔离级别是否真的能工作,先说下环境,spring3.1.2,mysql5,innob引擎。mysql配置的隔离级别是read-commit,用的是spring的jdbcTemplate直接操作数据库。
测试逻辑是这样的,两个进程T1,T2向数据库同一字段写入内容。然后通过改变隔离级别来验证spring事务是否有效。
线程T1 | 线程T2 |
读取字段name:1111 | |
休眠sleep,模拟业务处理 | 读取字段name:1111 |
休眠sleep,模拟业务处理 | 修改字段name:2222 |
修改字段name:1111 | |
是不是我的理解有误,还是不能用这种多线程去测试spring的事务,请高手帮忙解惑。
你的测试用例其实并不严谨。
T1, 因为它没有修改数据,所以,只要有基本的MVCC(多版本并发控制)的功能,就可以满足“可重复读”了,无论T2,T3,T4有没有修改数据,根本无需锁定表。 - 比如oracle,这时默认情况下,T1是从undo中读取"旧"数据。
再考虑数据库可能采用行锁,其实你要测试事务隔离级别的步骤应该是这样:
1. T1 T2 关闭autocommit;
2.T1 - select (开事务)
3.T2 - update t1看得到的记录(随便一条),注意不要commit
4.T1 - update T2中事务影响到的那条记录(此时,T1的事务就被挂起了)
5.T2 - 提交 - (这时,T1也解锁了)
要做这样的测试,其实用单纯的数据库客户端开两个SESSION还直观一些,无论是用mysql或postgresql或oracle都能完成这个测试。
确认用例正常后,再考虑多线程(JDBC),然后再考虑Spring的JDBCTemplate. 这样一步步做过去,出问题时,才容易找到原因,否则纠缠太多,不利于学习中的知识点各个击破。
T1和T2的连接会话中,autocommit必须是0才行。 如果autocommit=1(默认),那么T1 select后, 这个事务就结束了。
这时,即使select后,也要commit,否则锁表。
还有,这个测试跟spring无关啊
######明白你的意思了,不过spring在创建数据库连接时已经setAutoCommit=false,T1的所有操作都是在一个事务里面,只在最后提交。######因为是使用spring进行事务管理的,在配置里面将事务的隔离级别设置成了 REPEATABLE_READ,所以和spring有关吧。还有你说的autoCommit设置成0,是在哪里啊,mysql配置?版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。