图片.png
脏读
脏读指一个事务读取了另外一个事务未提交的数据。如果第一个事务这时候回滚了,那么第二个事务就读到脏数据了。
脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。
读脏数据.png
示例:
1、UserDao接口
public interface UserDao {
//读脏数据测试
public void insert1();
public List find1();
}
2、UserDaoImpl实现类
public class UserDaoImpl extends JdbcDaoSupport implements UserDao {
//读脏数据测试
@Transactional
public void insert1() {
String sql="insert into user(id,name,money) values(3,'王五',2222)";
getJdbcTemplate().update(sql);
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("新增结束!");
System.out.println(5/0);
}
//测试读脏数据
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
//解决脏读: @Transactional(isolation = Isolation.READ_COMMITTED)
public List find1(){
List list = getJdbcTemplate().queryForList("select * from user");
return list;
}
}
3、applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--1、指定数据源-->
<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/weifan"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg index="0" ref="datasource"></constructor-arg>
</bean>
<bean id="userDao" class="dao.impl.UserDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!--1、创建事务管理器对象-->
<bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"/>
</bean>
<!--① 对标注@Transactional注解的Bean进行加工处理,以织入事物管理切面 -->
<tx:annotation-driven transaction-manager="tx" />
</beans>
4、测试类
public class Test1 {
ApplicationContext app=
new ClassPathXmlApplicationContext("applicationContext.xml");
class A extends Thread{
public void run(){
System.out.println("查询线程开始");
UserDao dao=(UserDao) app.getBean("userDao");
for (int i = 0; i < 5; i++) {
List list=dao.find1();
System.out.println("list="+list);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class B extends Thread{
public void run(){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("新增线程开始");
UserDao dao=(UserDao) app.getBean("userDao");
dao.insert1();
}
}
public static void main(String[] args) {
//脏读
Test1 test1=new Test1();
Test1.A a=test1.new A();
Test1.B b=test1.new B();
a.start();
b.start();
}
}
测试结果
读脏数据结果.png
解决脏读:
@Transactional(isolation = Isolation.READ_COMMITTED)
解决读脏数据.png
网友评论