事务特性
原子性:不可分割,事务由多个原子组成,这些原子要么全成功,要么全失败。
一致性:事务在执行前与执行后数据保持一致。
隔离性:事务与事务之间不可以互相影响。
持久性:事务一旦commit,代表数据真正修改了,不可以在改变。
如果不考虑事务隔离性产生问题
- 脏读 一个事务读取到了另一个事务未提交数据
- 不可重复读 两次读取数据不一致 (读提交数据) update
- 虚读(幻读) 两次读取数据不一致 insert
1.脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
2. 不可重复读 :是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两 次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不 可重复读。
3. 幻读 : 是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。 同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象 发生了幻觉一样。
在开发中,要对事务隔离级别产生的问题解决,需要设置事务隔离级别。
数据库中的事务隔离级别有四种,这四种分别解决了以上三个问题.
spring默认的隔离级别是default,以具体的数据库隔离级别为准。
mysql: REPEATABLE_READ
ORACLE:READ_COMMITTED
事物的隔离级别
Default:使用后端数据库默认的隔离级别
Read_uncommited 允许你读取还未提交的改变了的数据。可能导致脏读,幻读,不可重读。
Read_commited允许在并发事物已经提交后读取。可以防止脏读,但幻读和不可重读扔可发生。
Repeatable_read对相同字段的读取是一致的,除非数据被事物本身改变。可防止脏读,不可重读,但幻读仍可能发生。
Serializable:确保不发生脏,幻,不可重读。这在所有的隔离级别中是最慢的。它是典型的通过事物通过完全锁定在事物中涉及的数据表来完成的。
传播行为
什么是事务传播行为? 有什么用?
事务传播行为用于解决两个被事务管理的方法互相调用问题。实际开发中将事务在service控制,如下方法调用存在传播行为:
class serviceA{
//此方法进行事务控制
funA(){
//在此方法中操作多个dao的操作,处于一个事务中
userDao.insertUser();
orderDao.insertOrder();
//如果在这里调用另一个service的方法,此时存在事务传播
serviceB.funB();
}
}
class serviceB{
funB(){
}
}
针对上边的问题:
如果serviceB也会产生一个代理对象,同时也会进行事务管理增强是,执行serviceA和serviceB分别开启事务,上边的serviceA中funA方法内容不处于一个事务中了!!!
解决方案:
设置serviceA和serviceB传播行为为REQURIED.
spring提供了传播行为:
注意:
required :可以将insert、update、delete这些service设置为required。
support : 可以将findList查询方法设置为support
对于查询事务,在事务定义 将isReadOnly设置true 性能更高。
spring去事务管理提供的支持
指在开发代码中,侵入式事务管理 ,通过TransactionTemplate完成
编程方式
一般开发中,不使用编程方式。
声明式事务
基于AOP思想,在创建目标对象时,为目标进行代理,通过环绕通知,动态为目标添加事务管理代码
声明式事务(xml方式)
搭建环境
jar包
导入基本jar (4个核心+2个日志)
测试 (1个)
AOP (4个)
Jdbc (2个 )
数据库驱动 (1个)
C3p0 连接池(1个)
配置文件
spring配置:applicationContext.xml
数据源:db.properties
日志:log4j.properties
service 和dao开发
在spring中配置service和dao