有个方法想使用read_uncommitted,但是一直不起作用,排查了半天终于发现了原因。
情景一:
这种情况下是可以读取到未commit
的数据的。
public class AService{
@Transactional(isolation=Isolation.READ_UNCOMMITTED)
public void fun(){
//这里可以读到脏数据
}
}
情景二:
AService
的一个READ_COMMITTED
方法调用BService
的一个READ_UNCOMMITTED
方法,这个时候是读取不到未commit
的数据的。
public class AService{
@Autowired
private BService bService;
@Transactional(isolation=Isolation.READ_COMMITTED)
public void fun2(){
bService.fun2();
}
}
public class BService{
@Transactional(isolation=Isolation.READ_UNCOMMITTED)
public void fun2(){
//这里不能读取到脏数据
}
}
另外:我用的是jpa hibernate
来保存的数据,在新增完的时候还需要flush
一下,否则上面两种情景都读取不到未提交数据。
下面是我的测试demo:
TestController.java
package com.channelsoft.apiplus.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.channelsoft.apiplus.po.AppDataResponsePo;
import com.channelsoft.apiplus.service.TestService;
@RestController("testController")
@RequestMapping(value = {"/myTest"})
public class TestController {
Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private TestService testService;
@ResponseBody
@RequestMapping(value = "/readUnCommitted2")
public JSONObject readUnCommitted2(HttpServletRequest request, HttpServletResponse response) {
logger.info("readUnCommitted2方法...");
AppDataResponsePo result = new AppDataResponsePo();
try{
new Thread(){
@Override
public void run() {
try {
testService.addReadUnCommitted();
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
new Thread(){
@Override
public void run() {
try {
int i = 0;
while(i++<10){
testService.loadOneReadUnCommitted();
testService.loadOneReadUnCommitted2();
Thread.sleep(5 * 1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();;
}catch(Exception e){
logger.error("errro:", e);
}
logger.info("readUnCommitted2方法 end.");
return (JSONObject) JSON.toJSON(result);
}
}
TestService.java
package com.channelsoft.apiplus.service;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import com.channelsoft.apiplus.entity.MyTest;
import com.channelsoft.apiplus.po.support.ApiConstants;
import com.channelsoft.apiplus.repository.mysql.TestDao;
@Service("testService")
@Component
@Transactional
public class TestService {
Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private TestDao testDao;
@Autowired
private Test2Service test2Service;
@Transactional(isolation=Isolation.READ_UNCOMMITTED)
public void loadOneReadUnCommitted() throws Exception{
MyTest test = null;
test = testDao.findOne(333l);
System.out.println(new Date() + "====TestService===" + test );
}
@Transactional
public void loadOneReadUnCommitted2() throws Exception{
test2Service.loadOneReadUnCommitted();
}
public void addReadUnCommitted() throws Exception{
MyTest test = new MyTest();
test.setOperationid(333l);
test.setContext("readUncommitted:" + new Date().toString());
test = testDao.save(test);
testDao.flush();//一定要flush,否则两个情景都读不到脏数据
System.out.println("after save=" + new Date() + test + "sleep 30s");
Thread.sleep(30 * 1000);
}
}
Test2Service.java
package com.channelsoft.apiplus.service;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import com.channelsoft.apiplus.entity.MyTest;
import com.channelsoft.apiplus.po.support.ApiConstants;
import com.channelsoft.apiplus.repository.mysql.TestDao;
@Service("test2Service")
@Component
//@Transactional
public class Test2Service {
Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private TestDao testDao;
@Transactional(isolation=Isolation.READ_UNCOMMITTED)
public void loadOneReadUnCommitted() throws Exception{
MyTest test = null;
test = testDao.findOne(333l);
System.out.println(new Date() + "====TestService2===" + test );
}
}
MyTest.java
package com.channelsoft.apiplus.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "OPERATION_LOG")
public class MyTest implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1668209570962416481L;
@Id
@Column(name = "operation_id")
private Long operationid;
@Column(name = "context")
private String context;
@Column(name = "operation_type")
private String operationtype;
@Column(name = "operation_time")
private String operationtime;
@Column(name = "operation_user")
private String operationuser;
@Column(name = "enterprise_id")
private String enterpriseid;
public String getOperationtime() {
return operationtime;
}
public void setOperationtime(String operationtime) {
this.operationtime = operationtime;
}
public String getOperationuser() {
return operationuser;
}
public void setOperationuser(String operationuser) {
this.operationuser = operationuser;
}
public String getEnterpriseid() {
return enterpriseid;
}
public void setEnterpriseid(String enterpriseid) {
this.enterpriseid = enterpriseid;
}
public Long getOperationid() {
return operationid;
}
public void setOperationid(Long operationid) {
this.operationid = operationid;
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
public String getOperationtype() {
return operationtype;
}
public void setOperationtype(String operationtype) {
this.operationtype = operationtype;
}
@Override
public String toString() {
return "MyTest [operationid=" + operationid + ", context=" + context + "]";
}
}
2016-10-14 15:52:31,065 [qtp1062664881-29] INFO c.c.a.controller.TestController - readUnCommitted2方法...
2016-10-14 15:52:31,067 [qtp1062664881-29] INFO c.c.a.controller.TestController - readUnCommitted2方法 end.
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:52:31 CST 2016====TestService===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:40:39 CST 2016]
2016-10-14 15:52:31,221 [qtp1062664881-29] DEBUG c.c.q.i.ApiCountInterceptor - Api[/apiplus/myTest/readUnCommitted2] is not in limit list,ignored.
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:52:31 CST 2016====TestService2===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:40:39 CST 2016]
Hibernate: update OPERATION_LOG set context=?, enterprise_id=?, operation_time=?, operation_type=?, operation_user=? where operation_id=?
after save=Fri Oct 14 15:52:31 CST 2016MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]sleep 30s
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:52:36 CST 2016====TestService===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:52:36 CST 2016====TestService2===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:40:39 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:52:41 CST 2016====TestService===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:52:41 CST 2016====TestService2===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:40:39 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:52:46 CST 2016====TestService===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:52:46 CST 2016====TestService2===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:40:39 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:52:51 CST 2016====TestService===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:52:51 CST 2016====TestService2===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:40:39 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:52:56 CST 2016====TestService===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:52:56 CST 2016====TestService2===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:40:39 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:53:01 CST 2016====TestService===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:53:01 CST 2016====TestService2===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:53:06 CST 2016====TestService===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:53:06 CST 2016====TestService2===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:53:11 CST 2016====TestService===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:53:11 CST 2016====TestService2===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:53:16 CST 2016====TestService===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]
Hibernate: select mytest0_.operation_id as operatio1_6_0_, mytest0_.context as context2_6_0_, mytest0_.enterprise_id as enterpri3_6_0_, mytest0_.operation_time as operatio4_6_0_, mytest0_.operation_type as operatio5_6_0_, mytest0_.operation_user as operatio6_6_0_ from OPERATION_LOG mytest0_ where mytest0_.operation_id=?
Fri Oct 14 15:53:16 CST 2016====TestService2===MyTest [operationid=333, context=readUncommitted:Fri Oct 14 15:52:31 CST 2016]