问一个mysql事务并发的问题

李海华 2013-05-24 08:17:42
在多线程中,线程A先开始调用事务business(),
然后线程B也开始调用同一事务business(),并进行了一个表一条记录一个字段进行如何操作。
1、修改
2、读取
3、修改
此时线程A等这个表解锁,直到线程B调用的事务结束,然后才对这个表同一记录同一字段进行同样操作,结果操作的竟是线程A修改前的值

我十分不解,线程B既然都已经结束了,应该持久化到数据库里,线程A为什么读到的竟是修改前的值。
而且在线程B开始前线程A在 1、修改 时等锁,也不存在读取线程B操作前的数据

mysql数据库
qq:290695839

请指点,非常感谢,今天在线等
...全文
313 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
冰思雨 2013-05-30
  • 打赏
  • 举报
回复
1.数据库事务是有隔离级别的。 看看你出现的状况满足数据库事务的那个隔离级别。 2.如果你查询出来的数据,不想被其他事务修改,就要将查询出来的记录锁住。 使用 select for update。 3.如果是频繁操作,注意性能问题。
冰思雨 2013-05-24
  • 打赏
  • 举报
回复
select for update
李海华 2013-05-24
  • 打赏
  • 举报
回复
注掉的代码是查询的另外一个单表,注掉前后结果如下,其中22、23、24是线程号 注掉那行代码时结果如下,是正确的,取的id是不同的 ---22 test 0 start INFO http-8080-1 org.springframework.aop.framework.DefaultAopProxyFactory - CGLIB2 available: proxyTargetClass feature enabled ---23 test 0 start ---24 test 0 start INFO http-8080-1 org.springframework.jdbc.datasource.JdbcTransactionObjectSupport - JDBC 3.0 Savepoint class is available ------24 taxStuGuidCase start ------23 taxStuGuidCase start ------22 taxStuGuidCase start ---------newId 24 23845 ---------newId 24 23846 ---------newId 24 23847 ---------newId 24 23848 ---------newId 24 23849 ---------newId 24 23850 ---------newId 24 23851 ---------newId 24 23852 ---------newId 24 23853 ---------newId 24 23854 ------24 taxStuGuidCase end ---------newId 22 23855 ---------newId 22 23856 ---------newId 22 23857 ---------newId 22 23858 ---------newId 22 23859 ---------newId 22 23860 ---------newId 22 23861 ---------newId 22 23862 ---------newId 22 23863 ---------newId 22 23864 ------22 taxStuGuidCase end ---24 test 0 end ---------newId 23 23865 ---------newId 23 23866 ---------newId 23 23867 不注掉那行代码时取的重复 ---22 test 0 start INFO http-8080-1 org.springframework.aop.framework.DefaultAopProxyFactory - CGLIB2 available: proxyTargetClass feature enabled ---23 test 0 start ---24 test 0 start INFO http-8080-2 org.springframework.jdbc.datasource.JdbcTransactionObjectSupport - JDBC 3.0 Savepoint class is available ------23 taxStuGuidCase start ------24 taxStuGuidCase start ------22 taxStuGuidCase start ---------newId 23 25225 ---------newId 23 25226 ---------newId 23 25227 ---------newId 23 25228 ---------newId 23 25229 ---------newId 23 25230 ---------newId 23 25231 ---------newId 23 25232 ---------newId 23 25233 ---------newId 23 25234 ------23 taxStuGuidCase end ---------newId 24 25225 ---------newId 24 25226 ---------newId 24 25227 ---------newId 24 25228 ---------newId 24 25229 ---------newId 24 25230 ---------newId 24 25231 ---------newId 24 25232 ---------newId 24 25233 ---------newId 24 25234 ------24 taxStuGuidCase end ---23 test 0 end ---------newId 22 25225 ---------newId 22 25226 ---------newId 22 25227 ---------newId 22 25228 ---------newId 22 25229 ---------newId 22 25230 ---------newId 22 25231
李海华 2013-05-24
  • 打赏
  • 举报
回复
嗯,上下代码 public void taxStuGuidCase(StuTestAnswerObj stuTestAnswerObj) throws Exception{ // 如果把下行这行代码注掉,下面取的id都是新的,不知为什么? List<PreCaseObj> preCaseObjList = DAOTool.getDAO(PreCaseDAO.class).findPreCaseObjsByGuidcaseId(2); for(int i=0;i<10;i++){ int id = NLLDDAOTool.getAutoID(StuTestQuestionObj.tablename); System.out.println("---------newId "+Thread.currentThread().getId() + " " + id); } }
无聊找乐 2013-05-24
  • 打赏
  • 举报
回复
内容太多,不是一句两句能说清楚的。 你可以看看事物的级别。 再看看数据库原理关于锁的部分, 事物级别:(看名字应该就能猜出来有什么不一样吧) Read Uncommitted Read Committed Repeatable Read Serializable
李海华 2013-05-24
  • 打赏
  • 举报
回复
我的是sping+jdbc,就是jdbcTemplate,应该不是延迟的问题
聪头 2013-05-24
  • 打赏
  • 举报
回复
理论上讲表应该是读取更改过的。 你应该是使用了hibernate类似的持久化方式。 首先不使用持久化,直接连数据库测试多线程,查看A的读取结果。应该就是正常情况。这说明是持久化过程有延迟,可能是缓存机制造成的,查看配置文件,取消缓存机制再测。 只要找到问题根源就能找到解决办法。
gloomyfish 2013-05-24
  • 打赏
  • 举报
回复
写事务会上锁,读事务也给不会上锁, 你这种情况,好像只能re-load! 个人观点,仅供参考!
leecyz 2013-05-24
  • 打赏
  • 举报
回复
需要看INNODB、MYIsam、事务、锁(读锁、写锁)。
leecyz 2013-05-24
  • 打赏
  • 举报
回复
问题精简点,优化一下了发出来,我是没看懂你说的啥
李海华 2013-05-24
  • 打赏
  • 举报
回复
你也挺好吧。 好像是我搞错了,一个事务开始到结束这中间,如果有其它事务修改了数据并提交,是读不到的,这是数据库的一个特性。我只能采用别的办法了。 谢谢
桃园闲人 2013-05-24
  • 打赏
  • 举报
回复
站长!好久不见!
桃园闲人 2013-05-24
  • 打赏
  • 举报
回复
你的Spring事务应该配置的是未提交读,即读取数据时不受锁得限制。用楼上的方式试试,或者修改事务配置。

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧