什么是事务:
事务指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败。
事务的特性:
原子性,隔离性,一致性,持久性。
原子性:指的是事务是一个不可分割的工作单位,事务的发生要么全部发生,要么全部都不发生。
隔离性:指的是当多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离。
一致性:指事务发生后,前后的数据完整性必须保持一致。
持久性:当事务一定提交,他对数据库中的数据的改变是永久的,即使数据库发生故障也不应该对其有任何影响。
Spring 事务管理高层抽象主要包括了3个接口:
platFormTransactionManager 事务管理器
TransactionDefinition 事务定义信息(隔离,传播,超时,只读)
TransactionStatus 事务具体运行状态
(1)platFormTranscationManager 是一个接口 有很多针对不同持久层的框架去选择不同的事务管理器
事务 | 说明 |
org.sprinframework.jdbc.datasource.DataSourceTransactionManager | 使用Spring JDBC或iBatis进行持久化数据时使用 |
org.springframework.orm.hibernate3.HibernateTranscationManager | 使用Hiber3.0版本进行持久化数据时使用 |
org.springframework.orm.jpa.JpaTranscationManager | 使用JPA进行持久化时使用 |
org.springframework.jdo.JdoTranscationManager | 当持久化机制是jdo时使用 |
org.springframework.transaction.jta.JtaTranscationManager | 使用一个JTA实现来管理事务,在一个事务跨越多个资源时必须使用 |
(2)TranscationDefinition
TransactionDefinition接口的常量中ISOLATION_开头的表示事物的隔离级别(4种)
没有的话隔离级别,会出现的问题:
脏读:一个事务读取到另外一个事务改写但还未提交的数据。如果这些数据被回滚,则读到的数据是无效的。
不可重复读:在同一个事务中,读到了另一个事务已经提交更新的数据返回结果不一样,导致这个事务中前后的查询结果不一致。
虚读或幻读:一个事务读取一些数据之后,另一个事务插入了一些记录,而导致这个事务中查询的数据不一致。(第二次读取,会读取到插入后一些数据)
看了上面的解释,感觉不可重复读和幻读很类似。
特意查一下资料:
不可重复读的重点在修改,你前后读取到的数据是不一样。
例子(我随便想的,可能不对):事务1,a查询卡里有1000元,事务2,有人转500到你的卡里,事务1还没有结束,它再次查询卡里的金额,显示为1500元。同一个事务中前后读取的信息不一致。
幻读的重点在新增或删除,同样的条件, 第1次和第2次读出来的记录数不一样。
例子(网上找的):目前工资为1000的员工有10人。 事务1,读取所有工资为1000的员工。 这时另一个事务向employee表插入了一条员工记录,工资也为1000 ,事务1再次读取所有工资为1000的员工 共读取到了11条记录,这就产生了幻像读。
隔离级别 | 含义 |
DEFAULT | 使用后端数据库默认的隔离级别(spring中的选择项) |
READ_UNCOMMITED | 允许你读取还未提交的改变了得数据,可能导致脏读,幻读,不可重复读 |
READ_COMMITED | 允许在并发事务已经提交读取,可防止脏读,但幻读和不可重复读仍可发生 |
REPEATABLE_READ | 对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏,不可重复读,但幻读仍可发生 |
SERIALIZABLE | 完全服从ACID(数据库事务的四要素)的隔离级别,确保不发生脏,幻,不可重复读。这在所有的隔离级别中是最慢的。他是典型的通过完全锁定在事务中涉及的数据表完成的。 |
mysql默认采用REPEATABLE_READ隔离级别
oracle默认采用READ_COMMITED隔离级别
TransactionDefinition接口的常量中PROPAGATION开头的表示事物的传播行为(7种)
当出现复杂情况时,比如某一个业务调用的业务层中的另外二个业务,每个业务都里面都有事务。
事务的传播行为:解决业务层方法之间的相互调用的问
事务传播行为类型 | 说明 |
PROPAGATION_REQUIRED | 支持当前事务,如果不存在,就新建一个 |
PROPAGATION_SUPPORTS | 支持当前事务,如果不存在,就不使用事务 |
PROPAGATION_MANDATORY | 支持当前事务,如果不存在,抛出异常 |
PROPAGATION_REQUIRES_NEW | 如果有事务存在,挂起当前事务,创建一个新的事务 |
PROPAGATION_NOT_SUPPORTED | 以非事务运行,如果有事务存在,挂起当前事务 |
PROPAGATION_NEVER | 以非事务运行,如果有事务存在,抛出异常 |
PROPAGATION_NESTED | 如果当前事务存在,则嵌套事务存在 |
Spring事务管理
Spring支持两种方式事务管理
--编程式的事务管理
在实际应用中很少使用
通过TranscationTemplate手动管理事务
--使用xml配置声明式事务
开发中推荐使用(代码侵入性最小)
Spring的声明式事务时通过aop实现的
原文:http://my.oschina.net/chenfwind/blog/521652