@Transactional注解的正确使用

Transactional是编程中的注解,也是声明事务的管理,要么全部执行成功,要么全部失败;

*使用方法:

1.添加在接口实现类或者接口实现方法上,而不是接口类中;
2.访问权限:public的方法才能起到作用,@Transactional注解应该只被应用到public方法上,这是由spring aop 的本质决定的,系统设计:将标签放在需要进行事务管理的方法上,而不是放在所有接口实现类上:制度的接口就不需要事务管理,由于配置了@Transactional就需要AOP拦截及事务的处理,可能影响系统性能;

3.错误使用:

(1).接口中A、B两个方法,A无@Transactional标签,B有,上层通过A间接调用B,此时事务不生效。

(2).接口中异常(运行时异常)被捕获而没有被抛出。默认配置下,spring 只有在抛出的异常为运行时 unchecked 异常时才回滚该事务,也就是抛出的异常为RuntimeException 的子类(Errors也会导致事务回滚),而抛出 checked 异常则不会导致事务回滚 。可通过 @Transactional rollbackFor进行配置。

(3).多线程下事务管理因为线程不属于 spring 托管,故线程不能够默认使用 spring 的事务,也不能获取spring 注入的 bean 。在被 spring 声明式事务管理的方法内开启多线程,多线程内的方法不被事务控制。一个使用了@Transactional 的方法,如果方法内包含多线程的使用,方法内部出现异常,不会回滚线程中调用方法的事务。

4.@Transctional注解:
实质是使用了JDBC的事务来进行事务控制,该注解是基于Spring的动态代理的机制

5.@Transactional实现原理:
<1>事务开始时,通过AOP机制,生成一个connection对象;
<2>将connection对象放入DataSource实例的一个与DataSourceTransactionManager相关的某处容器中;
<3>接下来的整个事务中,客户代码都使用该connection连接数据库;
<4>执行所有的数据库命令;
<5>在不使用connection链接数据库执行的数据库命令,在本次事务回滚的时候得不到回滚;
<6>物理连接connection逻辑上会新建一个会话session;
<7>DataSource与TransactionManager配置相同的数据源;
<8>事务结束时,回滚在第一步骤中得到的代理connection对象上执行的数据库命令;
<9>关闭该代理connection对象;
<10>事务结束后,回滚操作不会对已执行完毕的sql操作命令起作用;

6.声明式事务的管理实现本质:
事务的两种开启方式:
显示开启start transactional | begin,通过commit | rollback 结束事务
关闭数据库中自动提交 autocommit set autocommit = 0;MySql默认开启自动提交;通过手动提交或执行回滚操作来结束事务;

Spring关闭数据库中自动提交;在方法执行钱关闭自动提交,方法执行完毕后再开启自动提交;

问题:关闭自动提交后,若事务一直未完成,即未手动执行commit和rollback时如何处理已经执行过的sql操作?
C3P0默认的策略是回滚任何未提交的事务
C3P0是一个开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展,目前使用它的开源项目有Hibernate,Spring等;

7.spring事务特性
spring所有的事务管理策略类都继承自org.springframework.transaction.PlatformTransactionManager接口

事务的隔离级别:是指若干个并发的事务之间的隔离程度
事务的传播行为:如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为;

你可能感兴趣的:(数据库,oracle)