基于Spring JDBC的事务处理
事务(Transaction):在数据库中,可以保持一系列的数据操作要么全部执行成功,要么全部执行失败的机制!
假设存在以下信息:
账户 余额
阿三 1000
王五 8000
如果存在任务“王五向阿三转账5000元”,需要执行的SQL语句大致是:
update 账户信息表 set 余额=余额-5000 where 账户='王五';
update 账户信息表 set 余额=余额+5000 where 账户='阿三';
如果出现某种意外,导致以上第1条SQL语句成功执行了,第2条却无法执行或执行失败,就会出现数据安全问题(当然,把以上2条SQL语句的执行顺序对调后,出现以上状态也是不安全的)。
在以上这种“转账”的任务中,如果2条SQL语句都执行成功,就是预期的效果,但是,即使是2条SQL语句都执行失败了,数据安全也不会受到影响,也属于是可以接受的。
在基于Spring JDBC的编程中,只需要为业务方法加上@Transactional注解,就可以使得该业务方法中的多条数据操作是有事务的保障的,这多条数据操作要么全部成功,要么全部失败,不会出现成功一半且失败一半的问题!
框架在处理“事务”时,其大致的执行方式是:
try { 开启事务(BEGIN) 执行一系列的数据操作 提交事务(COMMIT) } catch (RuntimeException e) { 回滚事务(ROLLBACK) }
所以,在基于Spring JDBC的编程中,需要注意:
如果某个业务涉及2次或2次以上的增删改(例如2次UPDATE操作,或1次INSERT与1次DELETE,或其它)操作,必须在业务方法的声明之前添加@Transactional注解,以使得该业务的执行过程中是有事务的保障的;
在调用持久层的增删改操作时,必须及时获取返回的受影响行数,并判断受影响行数是否是预期值,如果不是,必须抛出RuntimeException或其子孙类异常!
另外,@Transactional注解还可以添加在业务类的声明之前,则当前业务类中所有业务方法都是有事务保障的,但是,通常没有这个必要性,所以,并不推荐这样使用!
课后,可自行了解:事务的ACID特性,事务的传播,事务的隔离。