1. 声明式事务
事务分为:编程式事务,声明式事务
编程式事务:程序员通过自己写的代码来控制事务机制
声明式事务:是基于spring aop来实现的,通知!
案例驱动:添加的同时,删除一条数据。
@Override public int addUser(User user) { int res = userMapper.addUser(user); res = userMapper.delete(43); return res; } |
结果:当删除语句出现问题的时候,添加却成功了!这说明这两条sql语句在两个事务中,正常来说,这两条sql语句应该属于同一事务!要么全部成功,要么全部失败!{spring框架提供简单的事务机制!
Spring 的功能都有什么?IOC, AOP,事务管理,对框架的支持!}
a) 是Spring提供的对程序事务管理的方式之一
b) 以方法为单位,进行事务控制;抛出异常,事务回滚。
1.1使用声明式事务步骤
1)添加命名空间
xmlns:tx=”http://www.springframework.org/schema/tx” http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd |
2)添加事务管理类 DataSourceTransactionManager:管理数据源
<!-- 配置事务管理器 --> <bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> |
3)配置事务通知:要知道在哪些方法上进行事务管理! 声明式事务,本质就是aop的通知。
<!-- 配置事务通知 --> <tx:advice id="txAdvice" transaction-manager="tx"> <tx:attributes> <!-- 配置事务传播特性:propagation:REQUIRED:每次查询的时候,看是否开启事务,如果没有开启事务,则开启事务 --> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="delete" propagation="REQUIRED"/> <tx:method name="update" propagation="REQUIRED"/> <!-- 以remove开通都开启事务管理:例如removeUser等 --> <tx:method name="remove*" propagation="REQUIRED"/> <!-- read-only只读 比如查询数据的时候 --> <tx:method name="get" read-only="true"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> |
4)配置事务切面
<!-- 配置切面 --> <aop:config> <aop:pointcut expression="execution(* com.bjsxt.service.impl.*.*(..))" id="pointcut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/> </aop:config>
配置声明式事务:其实,就是在配置Aop :相当于在前置通知中添加一个管理事务的类。DataSourceTransactionManager
|
1.2 事务的传播特性
传播特性 该特性是保证事务是否开启,业务逻辑是否使用同一个事务的保证。当事务在传播过程中会受其影响。其传播特性包括: 1、Propagation.REQUIRED 方法被调用时自动开启事务,在事务范围内使用则使用同一个事务,否则开启新事务。 2、Propagation.REQUIRES_NEW 无论何时自身都会开启事务 3、Propagation.SUPPORTS 自身不会开启事务,在事务范围内则使用相同事务,否则不使用事务 4、Propagation.NOT_SUPPORTED 自身不会开启事务,在事务范围内使用挂起事务,运行完毕恢复事务 5、Propagation.MANDATORY 自身不开启事务,必须在事务环境使用否则报错 6、Propagation.NEVER 自身不会开启事务,在事务范围使用抛出异常 7、Propagation.NESTED 如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。需要JDBC3.0以上支持。 |
1.3 事务隔离级别(isolation level)
在使用高并发多线程的时候,需要考虑。
脏读(Dirty reads)——脏读发生在一个事务读取了另一个事务改写但尚未提交的数据时。如果改写在稍后被回滚了,那么第一个事务获取的数据就是无效的。
不可重复读(Nonrepeatable read)——不可重复读发生在一个事务执行相同的查询两次或两次以上,但是每次都得到不同的数据时。这通常是因为另一个并发事务在两次查询期间进行了更新。
幻读(Phantom read)——幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录。
DEFAULT 默认值,Spring框架不参数事务隔离级别,受限于底层数据库.
READ_UNCOMMITTED:允许读取未提交数据,级别最低一种.可能出现脏读,不可重复读,幻读。效率快。
READ_COMMITTED:只允许读取提交后的数据.防止脏读,可能出现不可重复读和幻读.
REPEATABLE_READ: 只能读取到事务中已经提交的数据.可以防止脏读和不可重复读.可能出现幻读。
SERIALIZABLE:排队操作.最安全一种方式.效率最低的
什么单位,或者项目使用!~?
银行!安全!!!!!! Money!