当前位置:编程学习 > JAVA >>

问一个mysql事务并发的问题

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

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

mysql数据库
qq:290695839

请指点,非常感谢,今天在线等 --------------------编程问答-------------------- 理论上讲表应该是读取更改过的。

你应该是使用了hibernate类似的持久化方式。

首先不使用持久化,直接连数据库测试多线程,查看A的读取结果。应该就是正常情况。这说明是持久化过程有延迟,可能是缓存机制造成的,查看配置文件,取消缓存机制再测。

只要找到问题根源就能找到解决办法。 --------------------编程问答-------------------- 我的是sping+jdbc,就是jdbcTemplate,应该不是延迟的问题 --------------------编程问答-------------------- 内容太多,不是一句两句能说清楚的。

你可以看看事物的级别。 再看看数据库原理关于锁的部分,

事物级别:(看名字应该就能猜出来有什么不一样吧) 
Read Uncommitted
Read Committed
Repeatable Read
Serializable --------------------编程问答-------------------- 嗯,上下代码
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);
}
} --------------------编程问答-------------------- 注掉的代码是查询的另外一个单表,注掉前后结果如下,其中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 --------------------编程问答-------------------- select for update
--------------------编程问答-------------------- 你的Spring事务应该配置的是未提交读,即读取数据时不受锁得限制。用楼上的方式试试,或者修改事务配置。 --------------------编程问答-------------------- 站长!好久不见! --------------------编程问答-------------------- 你也挺好吧。
好像是我搞错了,一个事务开始到结束这中间,如果有其它事务修改了数据并提交,是读不到的,这是数据库的一个特性。我只能采用别的办法了。
谢谢 --------------------编程问答-------------------- 问题精简点,优化一下了发出来,我是没看懂你说的啥 --------------------编程问答-------------------- 需要看INNODB、MYIsam、事务、锁(读锁、写锁)。 --------------------编程问答-------------------- 写事务会上锁,读事务也给不会上锁,
你这种情况,好像只能re-load!
个人观点,仅供参考! --------------------编程问答-------------------- 1.数据库事务是有隔离级别的。
    看看你出现的状况满足数据库事务的那个隔离级别。

2.如果你查询出来的数据,不想被其他事务修改,就要将查询出来的记录锁住。
    使用 select for update。

3.如果是频繁操作,注意性能问题。
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,