Connection的事务隔离级别
Connection有5种隔离级别,用以下5个常量表示
隔离级别 | 描述 |
---|---|
TRANSACTION_NONE | 不支持事务 |
TRANSACTION_READ_UNCOMMITTED | 可以发生脏读 (dirty read)、不可重复读和虚读 (phantom read) |
TRANSACTION_READ_COMMITTED | 不可以发生脏读的常量;不可重复读和虚读可以发生。 |
TRANSACTION_REPEATABLE_READ | 不可以发生脏读和不可重复读的常量;虚读可以发生。 |
TRANSACTION_SERIALIZABLE | 不可以发生脏读、不可重复读和虚读 |
多个线程使用不同的Connection对象操作库表
设置不自动提交 connection.setAutoCommit(false);并且每个线程持有一个不同的connection对象
多个线程都执行update操作时,只有一个线程也就是只有一个connection可以更新成功,其他线程(connection)都在等待,哪怕把事务隔离级别设置为TRANSACTION_READ_UNCOMMITTED也不行,因为这个级别只是允许脏读而不是脏更新。所以上面的几种隔离级别只能用在一个connection做update,一个connection做select时的隔离。
但我在模拟一个connection做update,一个connection做select的场景时(使用两个线程,每个线程持有不同的connection,每个connection执行完都不commit)有时update的线程会报"Lock wait timeout exceeded"错误,但select查出的数据是已经update的数据。这就说明update成功了,但为什么update还要再等待锁就不知道了,请大神解释一下
下面是我的数据库、代码和输出
数据库
代码
entity类
package cn.lgc.study.spring.entity;
public class Name {
private String name;
private int num;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public Name(String name, int num) {
this.name = name;
this.num = num;
}
@Override
public String toString() {
return "Name [name=" + name + ", num=" + num + "]";
}
}
测试类
package cn.lgc.study.spring;
import java.util.concurrent.CountDownLatch;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import cn.lgc.study.spring.entity.Name;
import cn.lgc.study.spring.service.TestService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/applicationContext.xml")
public class TestServiceTest {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private TestService service;
@Test
public void testUpdate() throws InterruptedException {
String nm = "lgc998";
Name name1 = new Name(nm, 10);
Name name2 = new Name(nm, 20);
Runnable r1 = new RunModify(service, name1);
Runnable r2 = new RunSearch(service, name2);
new Thread(r1